python并发编程笔记7

python并发编程笔记7

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

视频链接:BV1bK411A7tV

老师的源码

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

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, "秒")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值