python并发编程笔记7

python并发编程笔记7,第1张

python并发编程笔记7

是根据蚂蚁学Python的视频做的笔记,方便自己后续回顾

视频链接:BV1bK411A7tV

老师的源码

这一份笔记对应的是视频的P11-P12

文章目录
  • python并发编程笔记7
  • P11-Python异步IO实现并发爬虫
    • 1、协程的本质:在单线程内实现并发
    • 2、Python 异步IO库介绍:asyncio
      • 注意:
    • 3、代码:
    • 对比总结:
  • P12-在异步IO中使用信号量控制爬虫并发度
    • 使用信号量控制爬虫并发度的目的:
    • 信号量(英语:Semaphore)
      • 使用方式1:
      • 使用方式2:
    • 代码:

P11-Python异步IO实现并发爬虫 1、协程的本质:在单线程内实现并发

线程是抢占式的,协程非抢占式,协程组织好的代码流程再运行,协程需要线程来承载运行。

多线程是假如你有一千个请求,线程启动时一瞬间全发出去,协程是依然是一个接着一个发,只不过在等待响应时切换到下一个请求任务。

线程调度是 *** 作系统层面的,协程是应用层面做的。

2、Python 异步IO库介绍:asyncio 注意:

要用在异步IO编程中
依赖的库必须支持异步IO特性

爬虫引用中:
requests 不支持异步
需要用 aiohttp

import asyncio

获取事件循环
loop = asyncio.get_event_loop()

# 定义协程
async def myfunc(url):
    await get_url(url)

# 创建task列表
tasks = [loop.create_task(myfunc(url)) for url in urls]

# 执行爬虫事件列表
loop.run_until_complete(asyncio.wait(tasks))
3、代码:
import asyncio
import aiohttp
import blog_spider
import time


# 定义协程
async def async_craw(url):
    print("craw url:", url)
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            result = await resp.text()
            print(f"craw url :{url},{len(result)}")


# 获取事件循环
loop = asyncio.get_event_loop()

# 创建task列表
tasks = [
    loop.create_task(async_craw(url))
    for url in blog_spider.urls]

start = time.time()

# 执行爬虫事件列表
loop.run_until_complete(asyncio.wait(tasks))

end = time.time()

print("async_craw,cost", end - start, "秒")
对比总结:

通过运行01的代码运行时间的对比,多线程与协程对比的话,多线程花费的时间要比协程多,主要是因为切换线程的开销

P12-在异步IO中使用信号量控制爬虫并发度 使用信号量控制爬虫并发度的目的:

加入一定数量的并发度,防止我们的爬虫将目标网站爬坏,超出他的处理能力

信号量(英语:Semaphore)

信号量(英语:Semaphore)又称为信号量、旗语
是一个同步对象,用于保持在0至指定最大值之间的一个计数值。

  • 当线程完成一次对该semaphore对象的等待(wait)时,该计数值减一;
  • 当线程完成一次对semaphore对象的释放(release)时,计数值加一。
  • 当计数值为0,则线程等待该semaphore对象不再能成功直至该semaphore对象变成signaled状态
  • semaphore对象的计数值大于0,为signaled状态;计数值等于0,为nonsignaled状态.
使用方式1:
sem = asyncio.Semaphore(10)

# ... later
async with sem:
    # work with shared resource
使用方式2:
sem = asyncio.Semaphore(10)

# ... later
await sem.acquire()
try:
    # work with shared resource
finally:
    sem.release()

代码:
import asyncio
import aiohttp
import blog_spider
import time

# 初始化一个信号量,10是并发度
semaphre = asyncio.Semaphore(10)


# 定义协程
async def async_craw(url):
    # 使用信号量控制爬虫并发度:
    async with semaphre:
        print("craw url:", url)
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as resp:
                result = await resp.text()
                # 为了可视化运行情况,加个5秒
                await asyncio.sleep(5)
                print(f"craw url :{url},{len(result)}")


# 获取事件循环
loop = asyncio.get_event_loop()

# 创建task列表
tasks = [
    loop.create_task(async_craw(url))
    for url in blog_spider.urls]

start = time.time()

# 执行爬虫事件列表
loop.run_until_complete(asyncio.wait(tasks))

end = time.time()

print("async_craw,cost", end - start, "秒")
r url in blog_spider.urls]

start = time.time()

# 执行爬虫事件列表
loop.run_until_complete(asyncio.wait(tasks))

end = time.time()

print("async_craw,cost", end - start, "秒")

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/923179.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-16
下一篇2022-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存