协程与多进程的完美结合

这是「进击的Coder」的第 607 篇技术分享

作者:kingname

来源:未闻 Code

阅读本文大概需要 4 分钟。

我们知道,协程本质上是单线程单进程,通过充分利用 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。在这样的场景里面,速度就是非常的重要,有时候就是需要做到越快越好。

关于aiomultiprocess的更多使用,可以参阅它的官方文档[1].

参考文献

[1] 官方文档: https://aiomultiprocess.omnilib.dev/en/latest/guide.html

491110fcba7a1be26eda9762ed052dad.png

End

崔庆才的新书《Python3网络爬虫开发实战(第二版)》已经正式上市了!书中详细介绍了零基础用 Python 开发爬虫的各方面知识,同时相比第一版新增了 JavaScript 逆向、Android 逆向、异步爬虫、深度学习、Kubernetes 相关内容,‍同时本书已经获得 Python 之父 Guido 的推荐,目前本书正在七折促销中!

内容介绍:《Python3网络爬虫开发实战(第二版)》内容介绍

1159a0cb468c0952aace7dfef254a65f.png

扫码购买

75cbbcee7052ce5ff1eb433e89ac6ddf.png

好文和朋友一起看~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值