python 3.5 asyncio 解释器如何处理 'suspended' 协程

标签 python python-3.5 python-asyncio

我是 asyncio 的新手,正在尝试了解它的实际工作原理。

假设我们有两个协程,其中一个看起来像这样:

async def f():
    await sleep(10)
    print('something')

显然,sleep() 可以是任何 IO 操作。 如果我对这段代码的理解正确,我们将开始执行 sleep(10) 并将上下文切换到其他一些协程(如果存在)。

但是如果这个协程被挂起,解释器如何“计算”那 10 秒呢?或者解释器如何处理某些 IO 响应,如果它发生在协程挂起时?

最佳答案

在内部 asyncio.sleep() 返回一个 Future 对象。 future 的值(value)将在超时到期后设置。

每个 coroutine 都由 asyncio.Task 执行。 future 冒泡到任务运行器(Task._step() 实际上)。 运行者向冒泡的 future 添加一个回调,以便在未来完成时唤醒自己。

sleep() 实现很简单:

@coroutine
def sleep(delay, result=None, *, loop=None):
    """Coroutine that completes after a given time (in seconds)."""
    if delay == 0:
        yield
        return result

    if loop is None:
        loop = events.get_event_loop()
    future = loop.create_future()
    h = future._loop.call_later(delay,
                                futures._set_result_unless_cancelled,
                                future, result)
    try:
        return (yield from future)
    finally:
        h.cancel()

任务运行器要复杂得多,但它的源代码仍然可读:https://github.com/python/asyncio/blob/master/asyncio/tasks.py#L223-L300

每个阻塞 IO 也会返回一个 future (可能来自非常深的内部调用)。当 IO 等待完成时,给定值(或异常)被分配给 future ,任务运行器被唤醒并恢复挂起的协程。

关于python 3.5 asyncio 解释器如何处理 'suspended' 协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40799981/

相关文章:

python - 光调频 : When do I make preserve_rows=True

python - 如何在python中以二进制模式下载大文件?

python - 有没有办法避免对此进行线性搜索?

python - subprocess.check_output 忽略 euid

python - 如何将python asyncio与线程结合起来?

python - Apache airflow 可以在 Windows 上使用吗?应该提前做什么?

python - 使用python读取和写入大文件

python - 'if'评估中的Python逻辑错误

python - Quart 应用程序如何从使用多个 worker 中受益?

python-3.x - Tornado + aioredis : why are my redis calls blocking?