Python 模块 asyncio-协程之间的同步

Python 模块 asyncio-协程之间的同步

虽然 asyncio 是运行在单线程模型上的,但是它的每个协程可能执行的顺序是不一致的,这要看超时、IO、网络或者其他的资源使用情况。所以 asyncio 为了支持安全的并发,从模块 threading 和 multiprocessing 引入了一些处理并发的单元。

锁 Locks


锁被用来保护访问的资源,只有获取锁后才可以访问资源,同一时间只有一个协程可以获取锁。

Python 模块 asyncio-协程之间的同步

执行:

Python 模块 asyncio-协程之间的同步

本例创建了两个协程,他们分别以两种方式获取和释放锁,一种使用 async with lock 语法,它会自动释放锁,另一种直接调用获取锁的方法 await lock.acquire(),然后使用 try:finally 释放锁。

因为 main() 协程一开始就获取锁了,需要等到 unlock() 方法执行释放锁后,两个协程才能获取锁。

事件 Events


asyncio.Event 基于 threading.Event,只有事件对象内部标志位设置了,其他的才会继续往下执行。

Python 模块 asyncio-协程之间的同步

执行:

Python 模块 asyncio-协程之间的同步

本例中,一开始的两个协程 c1() 和 c2() 等待事件对象被设置,当事件对象状态改变时,立刻执行。

条件 Conditions


条件(Condition)同步机制和 Events 类似,当调用 notify() 时,等待的协程就开始执行。

Python 模块 asyncio-协程之间的同步

执行:

Python 模块 asyncio-协程之间的同步

本例创建了5个消费者协程等待 Condition,wait() 直到所有的消费者协程执行完后才继续往下运行。manipulate_condition() 首先是释放了两个协程,然后使用 notify_all() 释放全部。

队列 Queues


asyncio.Queue 是一个 FIFO(first-in first-out)的数据结构,和 queue.Queue、multiprocessing.Queue 一样。

Python 模块 asyncio-协程之间的同步

执行:

Python 模块 asyncio-协程之间的同步

调用队列的 get() 和 put() 方法时,都需要 await,因为他们都是异步操作,从队列获取元素有可能队列为空,添加元素可能队列元素数量已经达到最大值。


分享到:


相關文章: