PEP 0492 - Python 3.5 异步关键字
PEP 0492 - Python 3.5 async keyword
PEP 0492 将 async
关键字添加到 Python 3.5。
Python 如何从使用此运算符中获益?协程的例子是
async def read_data(db):
data = await db.fetch('SELECT ...')
根据文档,这实现了
suspend[ing] execution of read_data coroutine until db.fetch awaitable completes and returns the result data.
这个 async
关键字是否真的涉及创建新线程或可能使用现有的保留异步线程?
如果 async
确实使用了保留线程,它是否是一个单独的共享线程?
不,协程不涉及任何类型的线程。协同例程允许 合作 多任务处理,因为每个协同例程都自愿放弃控制。另一方面,线程在任意点的单位之间切换。
在 Python 3.4 之前,可以使用 generators 编写协程;通过在函数体中使用 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)
每次上面的代码前进到yield from asyncio.sleep(1)
行,事件循环就自由运行一个不同的协程,因为这个例程下一秒不会做任何事情无论如何.
因为生成器可以用于各种任务,而不仅仅是协同例程,而且因为使用生成器语法编写协同例程可能会让新手感到困惑,所以 PEP 引入了新的语法,使其成为 更清楚你在写协程。
随着 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)
生成的coroutine
对象仍然需要一个事件循环来驱动协程;事件循环将依次 await
在每个协同例程上,这将执行那些当前 await
未完成某些事情的协同例程。
优点是有了原生支持,你还可以引入额外的语法来支持异步上下文管理器和迭代器。进入和退出上下文管理器,或遍历迭代器然后可以成为您的协同例程中的更多点,表明其他代码可以 运行 而不是因为有东西再次等待。
PEP 0492 将 async
关键字添加到 Python 3.5。
Python 如何从使用此运算符中获益?协程的例子是
async def read_data(db):
data = await db.fetch('SELECT ...')
根据文档,这实现了
suspend[ing] execution of read_data coroutine until db.fetch awaitable completes and returns the result data.
这个 async
关键字是否真的涉及创建新线程或可能使用现有的保留异步线程?
如果 async
确实使用了保留线程,它是否是一个单独的共享线程?
不,协程不涉及任何类型的线程。协同例程允许 合作 多任务处理,因为每个协同例程都自愿放弃控制。另一方面,线程在任意点的单位之间切换。
在 Python 3.4 之前,可以使用 generators 编写协程;通过在函数体中使用 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)
每次上面的代码前进到yield from asyncio.sleep(1)
行,事件循环就自由运行一个不同的协程,因为这个例程下一秒不会做任何事情无论如何.
因为生成器可以用于各种任务,而不仅仅是协同例程,而且因为使用生成器语法编写协同例程可能会让新手感到困惑,所以 PEP 引入了新的语法,使其成为 更清楚你在写协程。
随着 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)
生成的coroutine
对象仍然需要一个事件循环来驱动协程;事件循环将依次 await
在每个协同例程上,这将执行那些当前 await
未完成某些事情的协同例程。
优点是有了原生支持,你还可以引入额外的语法来支持异步上下文管理器和迭代器。进入和退出上下文管理器,或遍历迭代器然后可以成为您的协同例程中的更多点,表明其他代码可以 运行 而不是因为有东西再次等待。