我应该在另一个进程/线程中调用异步函数吗?

时间:2019-06-07 09:09:52

标签: python python-3.x python-asyncio

我正在用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())

1 个答案:

答案 0 :(得分:1)

  

我通过打开最多6个终端并运行脚本和   我最多可以得到6倍的性能。

由于pyppeteer已经是异步的,所以我想您只是没有并行运行多个浏览器,这就是为什么在运行多个进程时输出增加的原因。

要同时(“并行”)运行一些协程,通常使用类似asyncio.gather的方法。你有代码吗?如果答案为否,请检查this example-这是您应该运行多个作业的方式:

responses = await asyncio.gather(*tasks)

如果您已经使用asyncio.gather,请考虑提供Minimal, Reproducible Example,以便更容易理解发生的情况。