Python中的事件循环(async/await)

rmbxnbpk  于 2023-08-08  发布在  Python
关注(0)|答案(1)|浏览(87)

我有点糊涂了。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秒。看起来,生产控制不仅没有明显的开销,而且“看起来”它们同时进行。我还是不明白

编辑

一方面,它们在事件循环上顺序运行,另一方面,它们“看起来”是并发运行。这种效果是如何实现的?

disbfnqx

disbfnqx1#

用例1:Task1和Task2将被推送到event_loop中(可以看作一个队列)
Python会逐个运行协程,因此不会有资源竞争
情况2:当代码运行到异步睡眠状态时,它挂起并等待时间到来
因此第二个0,任务1和任务2将被挂起
5秒时,任务1唤醒并打印
7秒时,任务2唤醒
任务并发运行,但不并行运行
一次只会运行一个任务,但是主解释器可以在等待某些东西的同时被协程释放
这里有一篇关于异步的文章,你可以看看https://fastapi.tiangolo.com/async/#asynchronous-code

相关问题