我有点糊涂了。Asyncio具有单线程事件循环。所有的合作程序都在里面运行。如果我的协程没有任何await/yield,那么这样的协例程应该是原子的。为什么我应该同步访问全局变量(作为共享资源的示例)?
比如说,
import asyncio
global_var = 0
async def coroutine1():
global global_var
global_var += 1
async def coroutine2():
global global_var
global_var -= 1
async def main():
await asyncio.gather(coroutine1(), coroutine2())
asyncio.run(main())
字符串
我看没什么问题。
此外,如果协同例程确实产生了控制,则它将控制权产生给事件循环,该事件循环恢复另一个协同例程(如果可用)。因此,在这种情况下也不需要同步。
我哪里做错了?
编辑:
import asyncio
import time
async def task1():
await asyncio.sleep(5)
print("Task 1 done")
async def task2():
await asyncio.sleep(7)
print("Task 2 done")
async def main():
t_0 = time.time()
await asyncio.gather(task1(), task2())
print((int)(time.time() - t_0))
print("All tasks completed")
asyncio.run(main())
型
输出量:
任务1完成
任务2完成
7
所有任务已完成
max(5,7)=7秒。看起来,生产控制不仅没有明显的开销,而且“看起来”它们同时进行。我还是不明白
编辑:
一方面,它们在事件循环上顺序运行,另一方面,它们“看起来”是并发运行。这种效果是如何实现的?
1条答案
按热度按时间disbfnqx1#
用例1:Task1和Task2将被推送到event_loop中(可以看作一个队列)
Python会逐个运行协程,因此不会有资源竞争
情况2:当代码运行到异步睡眠状态时,它挂起并等待时间到来
因此第二个0,任务1和任务2将被挂起
5秒时,任务1唤醒并打印
7秒时,任务2唤醒
任务并发运行,但不并行运行
一次只会运行一个任务,但是主解释器可以在等待某些东西的同时被协程释放
这里有一篇关于异步的文章,你可以看看https://fastapi.tiangolo.com/async/#asynchronous-code