当使用下面的await asyncio.sleep(1)
运行代码时:
import asyncio
async def test1():
for _ in range(0, 3):
print("Test1")
await asyncio.sleep(1) # Here
async def test2():
for _ in range(0, 3):
print("Test2")
await asyncio.sleep(1) # Here
async def test3():
for _ in range(0, 3):
print("Test3")
await asyncio.sleep(1) # Here
async def call_tests():
await asyncio.gather(test1(), test2(), test3())
asyncio.run(call_tests())
test1()
、test2()
和test3()
交替运行,每次休眠1秒,如下所示:
Test1
Test2
Test3
Test1
Test2
Test3
Test1
Test2
Test3
现在,我想不睡觉地交替运行它们,但如果我从它们中删除await asyncio.sleep(1)
:
# ...
async def test1():
for _ in range(0, 3):
print("Test1")
# await asyncio.sleep(1)
async def test2():
for _ in range(0, 3):
print("Test2")
# await asyncio.sleep(1)
async def test3():
for _ in range(0, 3):
print("Test3")
# await asyncio.sleep(1)
# ...
它们按顺序运行,如下所示:
Test1
Test1
Test1
Test2
Test2
Test2
Test3
Test3
Test3
那么,我怎样才能不睡觉地交替运行它们呢?
2条答案
按热度按时间iqxoj9l91#
正如不同的人在评论中所说的那样,实现这一点的方法是调用
await asyncio.sleep(0)
,但重要的不是sleep
调用:如果值为0,则不会暂停,如果事件循环中没有挂起的任务,则会立即恢复代码。真正重要的是,必须通过等待协同例程或其他可等待对象的方式,显式地将控制权暂时返回给事件循环。如果没有
await <xxx>
语句,代码执行永远不会转移到事件循环,异步执行模型也无法运行其他任务中的任何代码:该模型是单线程的,它所做的是让异步循环在任务之间交替执行。等待某个东西是将控制传递给事件循环的方式。现在,如果你不是真的在等待某个异步函数完成,而只是想将控制传递给事件循环,给予其他任务有机会运行,没有特定的调用--所以使用asyncio.sleep(0)
。甚至 * 在Python标准库内的 * 官方 * 异步代码中使用它。例如:https://github.com/python/cpython/blob/main/Lib/asyncio/streams.py#L376当你在做这个的时候,检查实际的
asyncio.sleep
实现也同样简单,可以看到0和负值不会导致任何休眠:只需要让控制流到asyncio.loop:https://github.com/python/cpython/blob/1438b779971605e516bd0a4051a704d6ffbbd58d/Lib/asyncio/tasks.py#L630qq24tv8q2#
休眠0秒的
await asyncio.sleep(0)
可以不休眠交替运行,如下所示:这就是结果: