Асинхронные исполнители

Примечание. Использует асинхронный / ожидающий синтаксис Python 3.5+.

asyncio поддерживает использование Executor объектов , найденные в concurrent.futures для планирования задач асинхронна. Петли событий имеют функцию run_in_executor() , который принимает Executor объект, 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))

Есть два основных типа Executor в concurrent.futures , тем ThreadPoolExecutor и ProcessPoolExecutor . ThreadPoolExecutor содержит пул потоков , которые могут быть либо вручную для определенного числа потоков через конструктор по умолчанию или к количеству ядер на время машины 5. ThreadPoolExecutor использует пул потоков для выполнения задач , поставленных перед ней и обычно лучше при операциях с процессором, чем при операциях ввода-вывода. Контраст , что к ProcessPoolExecutor , который порождает новый процесс для каждой задачи , возложенной на него. ProcessPoolExecutor может принимать только задачи и параметры, которые пригодны для консервирования. Наиболее распространенными задачами, которые нельзя отлавливать, являются методы объектов. Если вы должны запланировать метод объекта в качестве задачи в Executor необходимо использовать ThreadPoolExecutor .