非同步執行器
注意:使用 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
中有兩種主要型別的 Executor
,ThreadPoolExecutor
和 ProcessPoolExecutor
。ThreadPoolExecutor
包含一個執行緒池,可以通過建構函式手動設定為特定數量的執行緒,也可以預設為機器上的核心數量為 5. ThreadPoolExecutor
使用執行緒池來執行分配給它的任務,並且通常更好地在 CPU 繫結操作而不是 I / O 繫結操作。與 ProcessPoolExecutor
形成對比,ProcessPoolExecutor
為分配給它的每個任務產生一個新程序。ProcessPoolExecutor
只能接受可選擇的任務和引數。最常見的不可修復任務是物件的方法。如果必須將物件的方法安排為 Executor
中的任務,則必須使用 ThreadPoolExecutor
。