如何在ASYNCIO模块的工作,为什么我更新的样本同步运行?(How does the asynci

2019-10-30 02:04发布

我曾尝试在Python 3.6 ASYNCIO以下代码:实施例1:

import asyncio
import time

async def hello():

    print('hello')
    await asyncio.sleep(1)
    print('hello again')

tasks=[hello(),hello()]    
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

输出为预期:

hello
hello
hello again
hello again

然后我想改变asyncio.sleep到另一个DEF:

async def sleep():
    time.sleep(1)

async def hello():

    print('hello')
    await sleep()
    print('hello again')


tasks=[hello(),hello()]    
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

输出:

hello
hello again
hello
hello again

现在看来,这是不是在异步模式下运行,但一个正常的同步模式。

现在的问题是:为什么不是在异步模式下运行,我怎样才能改变旧的同步模块为“异步”吗?

Answer 1:

ASYNCIO使用一个事件循环 ,这在队列中选择什么样的任务 (协程的一个独立的调用链)旁边的激活。 至于什么任务是准备做实际工作的事件循环可以做出明智的决策。 这就是为什么事件循环还负责建立连接和观看文件描述符和其他I / O原语; 它给人的事件循环的见解时,有I /正在进行或当结果可用来处理O操作之中。

每当你使用await ,还有就是控制返回到环路,则可以通过控制到另一个任务的机会。 其任务则是挑选执行依赖于具体实现; 在asyncio参考实现提供了多种选择 ,但也有其他的实现,如非常,非常有效uvloop实现 。

你的样品是还是异步的 。 它只是恰巧,通过更换await.sleep()与同步time.sleep()调用,一个新的协程函数中,您介绍2间的协同程序到任务callchain不屈服,因而在什么样的顺序,他们的影响被执行。 他们这似乎是同步的顺序执行是一个巧合 。 如果交换事件循环,或引进更多的协同程序(尤其是一些使用I / O),顺序很容易被再次不同。

此外,新的协同程序使用time.sleep() ; 这使得你的协同程序不合作 。 事件循环不通知你的代码正在等待( time.sleep()不会屈服!),所以没有其他的协同程序可以同时执行 time.sleep()正在运行。 time.sleep()根本不会返回或允许任何其他代码运行直到时间的请求量已经过去了。 与此对比asyncio.sleep()执行 ,其简单地产生的事件循环用call_later()钩 ; 事件循环现在知道该任务将不再需要任何注意,直到稍后的时间。

另见ASYNCIO:为什么不是无阻塞默认为如何任务的更深入的讨论和事件循环互动。 如果你必须运行无法进行合作阻塞,同步码 ,然后使用执行池中有一个单独的胎面或子进程执行,以腾出其他表现更好的任务事件循环阻塞代码。



文章来源: How does the asyncio module work, why is my updated sample running synchronously?