asyncio模块如何工作,为什么我的更新样本同步运行? [英] How does the asyncio module work, why is my updated sample running synchronously?

查看:77
本文介绍了asyncio模块如何工作,为什么我的更新样本同步运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Python 3.6中尝试了以下用于asyncio的代码: 范例1:

I have tried the following code in Python 3.6 for asyncio: Example 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更改为另一个定义:

Then I want to change the asyncio.sleep into another 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

似乎它不是在异步模式下运行,而是在正常的同步模式下运行.

It seems it is not running in an asynchronous mode, but a normal sync mode.

问题是:为什么它不以异步模式运行,如何将旧的同步模块更改为异步"模块?

The question is: Why is it not running in an asynchronous mode and how can I change the old sync module into an 'async' one?

推荐答案

Asyncio使用事件循环,该循环选择其中的 task (协程的独立调用链)接下来要激活的队列.事件循环可以明智地决定准备执行实际任务的任务.因此,事件循环还负责创建连接观看文件描述符和其他I/O原语;它使事件循环可以洞悉何时正在进行I/O操作或何时可以处理结果.

Asyncio uses an event loop, which selects what task (an independent call chain of coroutines) in the queue to activate next. The event loop can make intelligent decisions as to what task is ready to do actual work. This is why the event loop also is responsible for creating connections and watching file descriptors and other I/O primitives; it gives the event loop insight into when there are I/O operations in progress or when results are available to process.

无论何时使用await,都有机会将控制权返回到循环,然后可以将控制权传递给另一个任务.然后选择执行哪个任务取决于确切的实现. asyncio参考实现提供多种选择,但是还有其他实现,例如非常高效的 uvloop实现.

Whenever you use await, there is an opportunity to return control to the loop which can then pass control to another task. Which task then is picked for execution depends on the exact implementation; the asyncio reference implementation offers multiple choices, but there are other implementations, such as the very, very efficient uvloop implementation.

您的样本仍然是异步.碰巧的是,通过在新的协程函数内用同步的time.sleep()调用替换await.sleep(),您在任务调用链中引入了两个不产生的协程,从而影响了它们执行的顺序.以似乎同步的顺序执行它们是巧合.如果您切换了事件循环,或引入了更多的协程(尤其是一些使用I/O的协程),则顺序很容易再次不同.

Your sample is still asynchronous. It just so happens that by replacing the await.sleep() with a synchronous time.sleep() call, inside a new coroutine function, you introduced 2 coroutines into the task callchain that don't yield, and thus influenced in what order they are executed. That they are executed in what appears to be synchronous order is a coincidence. If you switched event loops, or introduced more coroutines (especially some that use I/O), the order can easily be different again.

此外,您的新协程使用time.sleep();这会使您的协程不合作.事件循环不会收到代码正在等待的通知(time.sleep()将不会产生!),因此在time.sleep()运行时,不能执行其他协程. time.sleep()只是不返回或不运行任何其他代码,直到经过请求的时间为止.将此与 asyncio.sleep()实现进行对比,它只需使用

Moreover, your new coroutines use time.sleep(); this makes your coroutines uncooperative. The event loop is not notified that your code is waiting (time.sleep() will not yield!), so no other coroutine can be executed while time.sleep() is running. time.sleep() simply doesn't return or lets any other code run until the requested amount of time has passed. Contrast this with the asyncio.sleep() implementation, which simply yields to the event loop with a call_later() hook; the event loop now knows that that task won't need any attention until a later time.

另请参见

Also see asyncio: why isn't it non-blocking by default for a more in-depth discussion of how tasks and the event loop interact. And if you must run blocking, synchronous code that can't be made to cooperate, then use an executor pool to have the blocking code executed in a separate tread or child process to free up the event loop for other, better behaved tasks.

这篇关于asyncio模块如何工作,为什么我的更新样本同步运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆