简介
在python中asyncio包的Lock提供基本的锁定机制,
Event支持异步事件等待,
Condition允许条件等待,
Semaphore管理资源计数,
BoundedSemaphore限制在一定范围内。
所有这些原语非线程安全,适用于协程间的同步。
队列Queue和PriorityQueue支持生产者-消费者模式,具有异步操作和可选的最大大小。
1 同步原语 Synchronization primitives
以下是一些关键同步原语。
锁:
Lock
Event
Condition
信号量:
Semaphore
BoundedSemaphore
ASYNCIO锁API被设计成接近的类threading 模块(Lock,Event, Condition,
Semaphore, BoundedSemaphore),但它没有超时参数。该 asyncio.wait_for()功能可用于在超时后取消任务。
2 锁具 Lock
示例
class asyncio.Lock(*, loop=None) # 非线程安全
# 原始锁对象,基元锁是一种同步基元。
# 原始锁只处于锁定 解锁两种状态
# 协程 已获得 acquire(), 与yield from 一起使用
# release()
yield from lock # 锁支持上下文管理协议。应该用作上下文管理表达式
获得锁
lock = Lock() ... yield from lock try: ... finally:
释放锁
lock.release()
上下文管理器
lock = Lock() .... with (yield from lock): ...
测试锁定对象的锁定状态
if not lock.locked(): yield from lock else: # lock is acquired
功能:
是否获得锁 locked() # 如果获得了锁,返回True
协程 获取锁 acquire()
释放锁 release()
3 事件 Event
Event 实现,异步等效于 threading.Event,实现事件对象的类。
事件管理一个标志(默认为false),该标志可用通过方法设置为true,并通过set()设置为false
class asyncio.Event(*, loop=None) # 非线程安全
方法
clear() # 内部标志位重置false,协程调用wait()将阻塞到set()被调用以再次将内部标志设置位true
is_set() #True当且仅当北部标志为true才返回
set() # 将内部标志设置为true
wait() # 协程
4 触发条件 Condition
触发 条件的实现,异步等效于threading.Condition。
此类实现条件变量对象,条件变量运行一个或多个协程等待,直达他们被另一个协程通知。
如果没有给出lock参数为None,则必须是一个Lock对象,并且用作基础锁,否则将Lock创建一个新对象并将其用作基础锁
class asyncio.Condition(lock=None, *, loop=None) # 非线程安全
获取基础锁,此方法将阻塞到解锁,然后再将其设置为lock并返回True
协程 acquire()
默认情况夏,唤醒一个协程等待这个情况(如果有)如果在调用此方法时调用协程尚未获取锁定 引发错误 RuntimeError
notify(n=1)
如获得了基础锁,则返回
locked()
唤醒等待这种情况的所有协程。此方法类似 notify() 但此方法是唤醒所有等待的协程,如果调用此方法时被调用协程尚未获取锁定,则触发 RuntimeError
notify_all()
无返回,释放基础锁,将其重置为解锁状态然后返回。未锁定的锁被调用时,引发RuntimeError
release()
等到收到通知,如果调用此方法时协程尚未获取锁定,
asyncio wait()
此方法释放基础锁,然后进行阻塞 直到被notify()等类似方法唤醒为止。唤醒后,它将重新获取锁并返回True
RuntimeError将触发
等到func变为真,func应为可调用的,结果解释为布尔值
asyncio wait_for(func)
5 信号量 Semaphores 信号
Semaphore 信号量实现。 此类管理一个内部计数器,计数器由每个acquire()调用递减,并由每个release()调用递增。
计数器永远不能低于0,当acquire()发现它为0时,将阻塞,直到其他协程调用release() 为止。
class asyncio.Semaphore(value=1, *, loop=None)
# 非线程安全
acquire 获取一个信号量,如果内部计数器在输入时大于零,将其递减一,并返回True。如果进入时为0,阻塞;等待其他协程调用release() 使其大于0,然后返回True
asyncio acquire()
locked 如果无法立即获取信号量返回 True
locked()
release释放信号量,使内部计数器加1,进入时为0,并且另一个协程正则等待再次变为0,唤醒该协程
release()
6 有界信号量
有界信号量实现,继承自Semaphore。 在release() 它是否将增加超过ValueError初始值的值
class asyncio.BoundedSemaphore(value=1, *, loop=None)
7 队列集
源代码: Lib / asyncio / queues.py
Queue
PriorityQueue
LifeQueue
ASYNCIO队列API被设计为接近的queue模块的类 asyncio.wait_for() 功能可用于在超时 后取消任务
8 队列
队列用于协程生产者和消费者协程,如果maxsize小于或等于零,队列大小无限。 如果maxsize大于0,当队列达到maxsize时将阻塞,直到被删除 yield from
class asyncio.Queue(Maxsize=0, *, loop=None) # >py3.44
压入和获取 put get
与标准库不同queue,可用可靠的知晓Queue的大小qsize(),因为单线程asyncio应用程序不会在 调用qsize()和在Queue上执行操作时被中断。
put(), get()
empty 如果队列为空返回True,否则返回False
empty()
full 如果有maxsize个条目在队列,则返回True。 如果Queue使用参数maxsize=0, 则full()用于不会为True
full()
异步 get 从队列删除并返回一个元素。如果队列为空,则等待,直到队列有元素
async get()
get_nowait从队列中删除并返回一个项目,立即返回一个队列中的元素,如果队列有值,引发异常QueueEmpty
get_nowait()
async join 阻塞直到队列所有项目都已获得并处理,每当将项目添加到队列时,未完成任务数量将增加。 当未完成任务数降至0,join() 取消阻止
async join()
async put 项目放入队列。如果队列已满,请等待空闲插槽可用再添加到项目
async put()
put_nowait 不阻塞的放一个元素入队列。如果没有空闲槽位,引发QueueFull异常
put_nowait()
qsize 队列中的项目数
qsize()
task_done 前面排队的任务已经完成,即get出来的元素相关操作已经完成。
task_done() # >py3.4.4
maxsize 队列中可存放的元素数量
maxsize