异步执行器

注意:使用 Python 3.5+ async / await 语法

asyncio 支持使用 concurrent.futures 中的 Executor 对象异步调度任务。事件循环具有 run_in_executor() 函数,它接受 Executor 对象,Callable 和 Callable 的参数。

Executor 安排任务

import asyncio
from concurrent.futures import ThreadPoolExecutor

def func(a, b):
    # Do time intensive stuff...
    return a + b

async def main(loop):
    executor = ThreadPoolExecutor()
    result = await loop.run_in_executor(executor, func, "Hello,", " world!")
    print(result)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main(loop))

每个事件循环还有一个默认Executor 插槽,可以分配给 Executor。要从循环中分配 Executor 并安排任务,请使用 set_default_executor() 方法。

import asyncio
from concurrent.futures import ThreadPoolExecutor

def func(a, b):
    # Do time intensive stuff...
    return a + b

async def main(loop):
    # NOTE: Using `None` as the first parameter designates the `default` Executor.
    result = await loop.run_in_executor(None, func, "Hello,", " world!")
    print(result)

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.set_default_executor(ThreadPoolExecutor())
    loop.run_until_complete(main(loop))

concurrent.futures 中有两种主要类型的 ExecutorThreadPoolExecutorProcessPoolExecutorThreadPoolExecutor 包含一个线程池,可以通过构造函数手动设置为特定数量的线程,也可以默认为机器上的核心数量为 5. ThreadPoolExecutor 使用线程池来执行分配给它的任务,并且通常更好地在 CPU 绑定操作而不是 I / O 绑定操作。与 ProcessPoolExecutor 形成对比,ProcessPoolExecutor 为分配给它的每个任务产生一个新进程。ProcessPoolExecutor 只能接受可选择的任务和参数。最常见的不可修复任务是对象的方法。如果必须将对象的方法安排为 Executor 中的任务,则必须使用 ThreadPoolExecutor