Kur*_*eek 5 python coroutine async-await python-asyncio
我正在尝试遵循https://docs.python.org/3/library/asyncio-task.html#coroutines中的示例;这是同时运行两个say_after
协程的代码片段:
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
# time.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(say_after(1, 'hello'))
task2 = asyncio.create_task(say_after(2, 'world'))
print(f"Started at {time.strftime('%X')}")
await task1
await task2
print(f"Finished at {time.strftime('%X')}")
if __name__ == "__main__":
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
如果我运行这个,我会发现开始和结束相隔两秒:
Started at 12:59:35
hello
world
Finished at 12:59:37
Run Code Online (Sandbox Code Playgroud)
但是,如果我替换await asyncio.sleep(delay)
为time.sleep(delay)
(上面代码片段中的注释行),我会发现它们相隔三秒,因此基本上是同步运行的:
Started at 13:00:53
hello
world
Finished at 13:00:56
Run Code Online (Sandbox Code Playgroud)
我不太明白这一点;即使任务本身包含同步代码,并行运行的并发任务的意义不是吗?为什么这个例子不再适用time.sleep()
于而不是asyncio.sleep()
?
我不太明白这一点;即使任务本身包含同步代码,并行运行的并发任务的意义不是吗?
并发!=并行。在编写asyncio
代码时,底层例程仍然必须将流程返回到事件循环以允许并发。不管怎样,GIL 仍然存在。
为什么此示例不再使用 time.sleep() 而不是 asyncio.sleep()?
这里的区别在于asyncio.sleep
挂起当前任务,允许其他任务运行。time.sleep
不,这是一个“阻塞”调用。使用的程序asyncio
仍然是单线程的(除非使用线程),这意味着time.sleep
阻止主线程中的执行并阻止整个程序,直到睡眠持续时间结束。
协程提供协作并发,而不是并行。
为了通过协程实现良好的并发性,协程中调用的任何代码都asyncio.run
必须以非阻塞方式编写。实际上,这意味着任务中运行的任何代码都有责任在暂停执行的好时机时让出,例如“我没有做任何有用的事情,因为我只是在等待 I/O ”,从而允许另一个任务使用事件循环。
归档时间: |
|
查看次数: |
1295 次 |
最近记录: |