what's Python asyncio.Lock() for?

user3761759

Is it because coroutines may be preempted in the future? Or it allows people to use yield from in critical section (which IMO shouldn't be encouraged)?

dano

You use it for the same reason you'd use a lock in threaded code: to protect a critical section. asyncio is primarily meant for use in single-threaded code, but there is still concurrent execution happening (any time you hit a yield from or await), which means sometimes you need synchronization.

For example, consider a function that fetches some data from a web server, and then caches the results:

async def get_stuff(url):
    if url in cache:
        return cache[url]
    stuff = await aiohttp.request('GET', url)
    cache[url] = stuff
    return stuff

Now assume that you've got multiple co-routines running concurrently that might potentially need to use the return value of get_stuff:

async def parse_stuff():
    stuff = await get_stuff()
    # do some parsing

async def use_stuff():
    stuff = await get_stuff()
    # use stuff to do something interesting

async def do_work():
     out = await aiohttp.request("www.awebsite.com")
     # do some work with out


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    parse_stuff(),
    use_stuff(),
    do_work(),
))

Now, pretend that fetching data from url is slow. If both parse_stuff and use_stuff run concurrently, each will be hit with the full cost of going over the network to fetch stuff. If you protect the method with a lock, you avoid this:

stuff_lock = asyncio.Lock()

async def get_stuff(url):
    async with stuff_lock:
        if url in cache:
            return cache[url]
        stuff = await aiohttp.request('GET', url)
        cache[url] = stuff
        return stuff

One other thing to note is that while one coroutine is inside get_stuff, making the aiohttp call, and another waits on stuff_lock, a third coroutine that doesn't need to call get_stuff at all can also be running, without being affected by the coroutine blocking on the Lock.

Obviously this example is a little bit contrived, but hopefully it gives you an idea of why asyncio.Lock can useful; it allows you to protect a critical section, without blocking other coroutines from running which don't need access to that critical section.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Python asyncio.Lock()的用途是什么?

来自分类Dev

What's the difference between first locking and creating a lock_guard(adopt_lock) and creating a unique_lock(defer_lock) and locking?

来自分类Dev

Python 3 asyncio-vs asyncio的收益

来自分类Dev

Python asyncio简单示例

来自分类Dev

Python的asyncio同步工作

来自分类Dev

Python asyncio调试示例

来自分类Dev

发送邮件python asyncio

来自分类Dev

python asyncio aiohttp超时

来自分类Dev

asyncio(python)如何工作?

来自分类Dev

理解python中的asyncio

来自分类Dev

Python asyncio 等待任务

来自分类Dev

asyncio python 3.6 代码到 asyncio python 3.4 代码

来自分类Dev

使用Slack bot的Python asyncio

来自分类Dev

python asyncio无效语法ubuntu

来自分类Dev

Python asyncio协议竞争条件

来自分类Dev

Python asyncio程序不会退出

来自分类Dev

将Python Cement与asyncio结合

来自分类Dev

Python unittest + asyncio永久挂起

来自分类Dev

Python asyncio wait_for同步

来自分类Dev

将Python Cement与asyncio结合

来自分类Dev

AsyncIO python3.4 restserver

来自分类Dev

python asyncio无效语法ubuntu

来自分类Dev

Python asyncio队列未更新

来自分类Dev

What format for a Python package's README on github?

来自分类Dev

使用Python的asyncio按顺序获取数据

来自分类Dev

Python asyncio取消未等待的协程

来自分类Dev

Python asyncio:收益不被用于未来吗?

来自分类Dev

Python Asyncio子进程永远不会完成

来自分类Dev

Python asyncio:函数或协程,使用哪个?