python - 我应该在另一个进程/线程中调用我的异步函数吗?
问题描述
我正在用 pyppeteer 截取数千个网页。我偶然发现,在 2 个打开的终端中运行相同的脚本会使我得到的输出加倍。我通过打开最多 6 个终端并运行脚本对此进行了测试,我能够获得高达 6 倍的性能。
我正在考虑使用loop.run_in_executor
在主程序的多个进程或线程中运行脚本。
这是正确的调用还是我在脚本中遇到了一些 IO/CPU 限制?
这就是我的想法。我不知道这是否是正确的做法。
import asyncio
import concurrent.futures
async def blocking_io():
# File operations (such as logging) can block the
# event loop: run them in a thread pool.
with open('/dev/urandom', 'rb') as f:
return f.read(100)
async def cpu_bound():
# CPU-bound operations will block the event loop:
# in general it is preferable to run them in a
# process pool.
return sum(i * i for i in range(10 ** 7))
def wrap_blocking_io():
return asyncio.run(blocking_io())
def wrap_cpu_bound():
return asyncio.run(cpu_bound())
async def main():
loop = asyncio.get_running_loop()
# Options:
# 1. Run in the default loop's executor:
result = await loop.run_in_executor(
None, wrap_blocking_io)
print('default thread pool', result)
# 2. Run in a custom thread pool:
with concurrent.futures.ThreadPoolExecutor(max_workers=6) as pool:
result = await loop.run_in_executor(
pool, wrap_blocking_io)
print('custom thread pool', result)
# 3. Run in a custom process pool:
with concurrent.futures.ProcessPoolExecutor(max_workers=6) as pool:
result = await loop.run_in_executor(
pool, wrap_cpu_bound)
print('custom process pool', result)
asyncio.run(main())
解决方案
我通过打开最多 6 个终端并运行脚本对此进行了测试,我能够获得高达 6 倍的性能。
由于pyppeteer
已经是异步的,我认为您只是不并行运行多个浏览器,这就是为什么在运行多个进程时会增加输出。
要同时运行一些协程(“并行”),您通常使用类似asyncio.gather的东西。你的代码有吗?如果答案是否定的,请查看此示例- 这就是您应该运行多个作业的方式:
responses = await asyncio.gather(*tasks)
如果您已经使用asyncio.gather
考虑提供最小的、可重现的示例,以便更容易理解发生了什么。
推荐阅读
- django - NOT NULL 约束失败:articles_comment.article_id
- kubernetes - Prometheus 导出器应该作为 sidecar 容器运行还是在单独的部署中运行?
- node.js - 打字稿错误:量角器中的“未知”类型不存在属性“清除”或“发送”
- javascript - new FormData(form) 不提交表单
- python - 局部变量、类变量和实例变量的名称解析不一致
- django - 如何在 Django 中将括号添加到 CheckConstraint
- angular - 如何使用 Angular 7 在 IE 11 中打印字节数组
- google-cloud-platform - 如何设置 Google Cloud Function (Python) 以创建 Google Cloud 项目?
- azure - 逻辑应用发送网格连接器未正确格式化电子邮件
- microsoft-cognitive - 1002 - 训练请求无效或缺少必需的参数