第十章:使用进程、线程和协程提供并发性-asyncio:异步I/O、事件循环和并发工具-同步原语-锁

10.5.7 同步原语
尽管asyncio应用通常作为单线程的进程运行,不过仍被构建为并发应用。由于I/O以及其他外部事件的延迟和中断,每个协程或任务可能按一种不可预知的顺序执行。为了支持安全的并发执行,asyncio包含了threading和multiprocessing模块中一些底层原语的实现。

10.5.7.1 锁
Lock可以用来保护对一个共享资源的访问。只有锁的持有者可以使用这个资源。如果有多个请求要得到这个锁,那么其将会阻塞,以保证一次只有一个持有者。

import asyncio
import functools

def unlock(lock):
    print('callback releasing lock')
    lock.release()

async def coro1(lock):
    print('coro1 waiting for the lock')
    with await lock:
        print('coro1 acquired lock')
    print('coro1 released lock')


async def coro2(lock):
    print('coro2 waiting for the lock')
    await lock
    try:
        print('coro2 acquired lock')
    finally:
        print('coro2 released lock')
        lock.release()

async def main(loop):
    # Create and acquire a shared lock.
    lock = asyncio.Lock()
    print('acquiring the lock before starting coroutines')
    await lock.acquire()
    print('lock acquired:{}'.format(lock.locked()))

    # Schedule a callback to unlock the lock.
    loop.call_later(0.1,functools.partial(unlock,lock))

    # Run the coroutines that want to use the lock.
    print('waiting for coroutines')
    await asyncio.wait([coro1(lock),coro2(lock)]),


event_loop = asyncio.get_event_loop()
try:
    event_loop.run_until_complete(main(event_loop))
finally:
    event_loop.close()

锁可以直接调用,使用await来得到,并且使用结束时可以调用release()方法释放锁,如这个例子中的coro2()所示。还可以结合with await关键字使用锁作为异步上下文管理器,如coro1()中所示。
运行结果:
第十章:使用进程、线程和协程提供并发性-asyncio:异步I/O、事件循环和并发工具-同步原语-锁_第1张图片
注:高版本python提示用async with lock替换with await lock。

你可能感兴趣的:(Python标准库)