协程与多进程的完美结合
我们知道,协程本质上是单线程单进程,通过充分利用IO等待时间来实现高并发。在IO等待时间之外的代码,还是串行运行的。因此,如果协程非常多,多少每个协程内部的串行代码运行时间超过了IO请求的等待时间,那么它的并发就会有一个上限。
举个例子,电饭煲煮饭,洗衣机洗衣服,热水壶烧水,他们都是启动设备以后就能自己运行,我们可以利用他们自己运行的时间,让这三件事情看起来几乎在同时进行。但如果除了这三件事情外,还有开电视,开空调,发微信……等等几十个事情。每个事情单独拿出来确实都只需要做个开头,剩下的就是等,但由于做这个开头也需要时间,因此把他们全部启动起来也要不少时间,你的效率还是被卡住。
现在,如果有两个人一起来做这些事情,那情况就不一样了。一个人煮饭和烧水,另一个人开洗衣机,开电视和空调。效率进一步提升。
这就是协程与多进程的结合,每个进程里面多个协程同时运行,充分利用CPU的每一个核心,又充分利用了IO等待时间,把CPU跑满,把网络带宽跑满。强强联合,速度更快。
有一个第三方库aiomultiprocess,让你能用几行代码就实现多进程与协程的组合。
首先使用pip安装:
python3 -m pip install aiomultiprocess
它的语法非常简单:
from aiomultiprocess import Pool
async with Pool() as pool:
results = await pool.map(协程, 参数列表)
只需要3行代码,它就会在你CPU上每个核启动一个进程,每个进程中不停启动协程。
我们来写一段实际代码:
import asyncio
import httpx
from aiomultiprocess import Pool
async def get(url):
async with httpx.AsyncClient() as client:
resp = await client.get(url)
return resp.text
async def main():
urls = [url1, url2, url3]
async with Pool() as pool:
async for result in pool.map(get, urls):
print(result) # 每一个URL返回的内容
if __name__ == '__main__':
asyncio.run(main())
之前我写异步协程文章的时候,有些人同学会问我,爬虫的速度真的那么重要吗?难道不是突破反爬虫最重要吗?
我的回答是,不要看到用aiohttp请求网址就觉得是做爬虫。在微服务里面,自己请求自己的HTTP接口,也需要使用httpx或者aiohttp。在这样的场景里面,速度就是非常的重要,有时候就是需要做到越快越好。
以上就是本次分享的所有内容,想要了解更多欢迎前往公众号:Python 编程学习圈,每日干货分享
- 介绍一款能取代 Scrapy 的爬虫框架 - feapder
- 直观讲解一下 RPC 调用和 HTTP 调用的区别!
- MySQL 亿级数据分页的优化
- Python 多线程小技巧:比 time.sleep 更好用的暂停写法!
- Python面试官:请说说并发场景锁怎么用?
- Python如何异步发送日志到远程服务器?
- Python 中的数字到底是什么?
- 如何建立一个完美的 Python 项目?
- 详解 Python 的二元算术运算,为什么说减法只是语法糖?
- Python 为什么没有 main 函数?为什么我不推荐写 main 函数?
- Bug分析,假删除导致文章发布成功却打不开的问题
- Python 进阶:queue 队列源码分析
- Python实例篇:自动操作Excel文件(既简单又特别实用)
- 谁说程序员不懂浪漫,当代码遇到文学..
- Python 为什么没有 void 关键字?
- 编程语言中分号“;”的简明历史
- Python 什么情况下会生成 pyc 文件?
- 函数和方法的装饰器
- Python 任务自动化工具:nox 的配置与 API
- 你可能不知道的 Python 技巧