Pau*_*son 34 python asynchronous coroutine python-3.x async-await
PEP 0492将async
关键字添加到Python 3.5.
Python如何从使用此运算符中受益?协程的例子是
async def read_data(db):
data = await db.fetch('SELECT ...')
Run Code Online (Sandbox Code Playgroud)
根据这个文件实现
暂停执行read_data协同程序,直到db.fetch等待完成并返回结果数据.
此async
关键字是否实际涉及新线程的创建或可能使用现有的保留异步线程?
在async
确实使用保留线程的情况下,它们各自是一个共享线程吗?
Mar*_*ers 44
不,协同例程不涉及任何类型的线程.协同例程允许协作多任务,因为每个协同例程都自愿地产生控制.另一方面,线程在任意点的单元之间切换.
直到Python 3.4,才有可能使用生成器编写协同例程; 通过在函数体中使用yield
或yield from
表达式来创建生成器对象,其中代码仅在迭代生成器时执行.与其他事件循环库(例如asyncio
)一起,您可以编写协同例程,这些协同例程将向一个事件循环发出信号,告知它们将要忙(等待I/O),并且可以同时运行另一个协同例程:
import asyncio
import datetime
@asyncio.coroutine
def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
yield from asyncio.sleep(1)
Run Code Online (Sandbox Code Playgroud)
每次上面的代码前进到该yield from asyncio.sleep(1)
行时,事件循环可以自由运行不同的协同例程,因为这个例程无论如何都不会为下一秒做任何事情.
因为生成器可以用于各种任务,而不仅仅是协同例程,并且因为使用生成器语法编写协同例程可能会让新人感到困惑,所以PEP引入了新的语法,使您更清楚地知道您正在编写co -常规.
实施PEP后,上述样本可以改为:
async def display_date(loop):
end_time = loop.time() + 5.0
while True:
print(datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(1)
Run Code Online (Sandbox Code Playgroud)
生成的coroutine
对象仍然需要一个事件循环来驱动协同例程; await
依次对每个协同例程进行事件循环,这将执行那些当前没有await
完成某些事情的协同例程.
优点是,通过本机支持,您还可以引入其他语法来支持异步上下文管理器和迭代器.进入和退出上下文管理器,或循环遍历迭代器,然后可以在您的协同例程中成为更多的点,表明其他代码可以运行,因为有些东西在等待.