Asyncio模块:异步执行者
注意:使用Python 3.5+异步/等待语法
Asyncio支持使用在并发中找到的执行器对象.Futures异步调度任务。
事件循环具有run_in_executor()的函数run_in_executor(),它采用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和计划任务,请使用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中有两种主要类型的执行器,ThreadPoolExecutor和ProcessPoolExecutor。ThreadPoolExecutor包含一个线程池,可以通过构造函数手动设置为特定的线程数,也可以默认为机器上的内核数乘以5。ThreadPoolExecutor使用线程池执行分配给它的任务,通常在CPU限制的操作上比I/O限制的操作更好操作。与ProcessPoolExecutor相比,ProcessPoolExecutor为分配给它的每个任务生成一个新进程。ProcessPoolExecutor只能接受可拾取的任务和参数。最常见的不可拾取任务是对象的方法。如果必须在执行器中将对象的方法安排为任务,则必须使用ThreadPoolExecutor。
Asyncio模块:协同程序和委托语法
在python3.5+发布之前,asyncio模块使用生成器模拟异步调用,因此其语法与当前的python3.5版本不同。
Python 3.x 版本 ≥ 3.5
python3.5引入了async和await关键字。请注意,await func()调用周围缺少括号。
import asyncio async def main(): print(await func()) async def func(): Do time intensive stuff… return "Hello, world!" if name == "main": loop = asyncio.get_event_loop() loop.run_until_complete(main())
Python 3.x版本≥3.3版本<3.5
在Python3.5之前,@asyncio.coroutine decorator用于定义协同程序。表达产物用于生成器委托。注意func()的yield的圆括号。
import asyncio @asyncio.coroutine def main(): print((yield from func())) @asyncio.coroutine def func(): Do time intensive stuff.. return "Hello, world!" if name == "main": loop = asyncio.get_event_loop() loop.run_until_complete(main())
Python 3.x版本≥3.5 Asyncio示例
以下是一个示例,其显示如何异步运行两个函数:
import asyncio async def cor1(): print("cor1 start") for i in range(10): await asyncio.sleep(1.5) print("cor1", i) async def cor2(): print("cor2 start") for i in range(15): await asyncio.sleep(1)
print("cor2", i) loop = asyncio.get_event_loop() cors = asyncio.wait([cor1(), cor2()]) loop.run_until_complete(cors)
Asyncio模块:使用UVLoop
UVLoop是基于Libuv(由NodeJS使用)的Asyncio.AbstractEventLoop的实现。
它符合99%的Asyncio功能,比传统的Asyncio.EventLoop更快。
UVLoop目前无法在Windows上使用,请使用pip安装UVLoop安装。
import asyncio import uvloop if name == "main": asyncio.set_event_loop(uvloop.new_event_loop())
人们还可以通过将EventLoopPolicy设置为UVLoop中的ONE来更改事件循环工厂。
import asyncio import uvloop if name == "main": asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) loop = asyncio.new_event_loop()