Python 协程间同步问题如何解决

可能是写 go 写多了,python3 用 asyncio,就一直想着把多个协程的结果写到一个 queue 里,然后再一个协程从 queue 里读数据处理,这种模式。 python3 刚学没多久,见识少,有谁知道异步 python 代码,有没有官方的最佳实践,有相应的项目链接就行,谢了。


Python 协程间同步问题如何解决
6 回复

python3 的协程间都是共享的,你直接用一个列表就行了,都单线程的,共享内存


对于Python协程间的同步,主要用asyncio提供的锁和信号量。最常用的是asyncio.Lock,保证一段代码在同一时间只被一个协程执行。

import asyncio

async def task(lock, name):
    async with lock:  # 获取锁
        print(f"{name} 进入临界区")
        await asyncio.sleep(1)  # 模拟耗时操作
        print(f"{name} 离开临界区")

async def main():
    lock = asyncio.Lock()
    # 创建多个并发任务
    tasks = [task(lock, f"Task-{i}") for i in range(3)]
    await asyncio.gather(*tasks)

asyncio.run(main())

asyncio.Semaphore用来限制同时运行的协程数量,比如控制并发请求数:

import asyncio

async def limited_task(sem, name):
    async with sem:
        print(f"{name} 开始")
        await asyncio.sleep(1)
        print(f"{name} 结束")

async def main():
    sem = asyncio.Semaphore(2)  # 最多同时2个
    tasks = [limited_task(sem, f"Task-{i}") for i in range(5)]
    await asyncio.gather(*tasks)

asyncio.run(main())

还有个asyncio.Event用于协程间的通知机制,一个协程wait()等事件,另一个set()触发所有等待者。

简单说就是:共享资源用Lock,限流用Semaphore,通知用Event。

协程直接可以共享结果,直接传递结果

Python 协程同步, 也有 Lock、Queue、Condition 之类的, 没有的话,自己实现一个也很容易

asyncio.Queue. 不过默认没有 go channel 的 close 功能,

python 协程本来就是 future 调用链,单线程又是线程安全的,想实现 go 的 channel 逻辑很简单吧
用两个变量,一个数组一个 await 等待对象,处理协程运行的时候判断下数组为空则创建一个 future 对象赋值给 await,然后等待 await 对象激活,数据协程则先往数据组中存入数据,判断下 await 对象存在且未激活就激活 await 对象,这时候处理协程就返回开始运行,取出数组数据处理就完了

回到顶部