python asyncio内置锁实现和扩展
asyncio也存在锁机制,可以保证在同一时刻只有一个协程访问资源。
关键方法是acquire与release。前者会创建一个future对象并加入队列,然后await这个future对象。release方法则取出这个对象并设置结果。
acquire方法关键代码片段
if self._waiters is None:
self._waiters = collections.deque()
fut = self._loop.create_future()
self._waiters.append(fut)
try:
await fut
finally:
self._waiters.remove(fut)
基于asyncio锁的超时锁: 虽然asyncio的Lock自身没有提供超时机制,但是可以经过简单的封装实现超时控制。
class TimeoutLock(asyncio.Lock):
def __init__(self, timeout, *args, **kwargs):
super().__init__(*args, **kwargs)
self.timeout = timeout
async def acquire(self) -> Literal[True]:
try:
return await asyncio.wait_for(super().acquire(), self.timeout)
except TimeoutError:
print(ColorMessage.yellow("LOCK TIMEOUT"))
raise
实现锁的context管理
with是python提供的便捷的资源管理方式。值得关注的是python同样支持async with语法,需要类实现__aenter__和__aexit__方法
async def __aenter__(self):
# assert self.handle_lock.locked()
try:
await self.timeout_lock.acquire()
self.locked = True
finally:
self.handle_lock.release()
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.locked:
self.timeout_lock.release()
浙公网安备 33010602011771号