【发布时间】:2015-11-30 10:03:23
【问题描述】:
import asyncio
l = asyncio.Lock()
async def test():
print('locked' if l.locked() else 'unlocked')
await l.acquire()
# await asyncio.ensure_future(l.acquire())
await asyncio.sleep(1)
l.release()
async def main():
await asyncio.gather(test(), test())
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
我们启动两个test()协程,第一个立即通过l.acquire()锁定Lock,第二个打印locked状态。输出:
unlocked
locked
如果您评论await l.acquire() 行并取消下一行的评论,一切都会改变。输出将是:
unlocked
unlocked
这是因为包裹在 Task 中的 l.acquire() 在第二个 test() 启动之后启动。
有没有办法让l.acquire() 任务在第二个test() 之前尽快启动(并获得与原始代码相同的输出)?
【问题讨论】:
-
我猜这是不可能的,因为事件循环以它们到达的相同顺序将任务从
_ready双端队列中弹出。在你的例子中,这个顺序是main(),test()、test()、l.acquire()。但是你为什么要把l.acquire()安排成一个任务呢? -
@Vincent 这是合成的例子,在现实生活中我使用
asyncio.gather(l1.acquire(), l2...)之类的东西来启动并行资源阻塞,但它在任务中包装了协程。 -
好的,所以它与您的other question 有关。也许
asyncio.gather不是适合这项工作的工具... -
@Vincent 谢谢,但这也是我的问题 :) 我需要解决这个问题才能找到第二个问题的答案。
标签: python python-3.x python-asyncio