【问题标题】:Is there a special syntax for suspending a coroutine until a condition is met?是否有一种特殊的语法可以暂停协程直到满足条件?
【发布时间】:2020-01-19 19:21:29
【问题描述】:

我需要暂停一个协程,直到满足一个条件。目前,我有:

class Awaiter:
    def __init__(self):
        self.ready = False

    def __await__(self):
        while not self.ready:
            yield

以及调用者代码:

await awaiter

这可行,但它需要样板代码。是否需要样板文件或是否有特殊语法等待谓词,例如:

await condition

在条件为假之前哪个会产生?

【问题讨论】:

    标签: python coroutine


    【解决方案1】:

    asyncio 包中有一个内置的Condition 对象可供您使用。

    任务可以使用异步条件原语来等待某个事件发生,然后获得对共享资源的独占访问权。

    如何使用条件(来自同一来源):

    cond = asyncio.Condition()
    
    # The preferred way to use a Condition is an async with statement
    async with cond:
        await cond.wait()
    
    # It can also be used as follow
    await cond.acquire()
    try:
        await cond.wait()
    finally:
        cond.release()
    

    代码示例:

    import asyncio
    
    cond = asyncio.Condition()
    
    async def func1():
        async with cond:
            print('It\'s look like I will need to wait')
            await cond.wait()
            print('Now it\'s my turn')
    
    async def func2():
        async with cond:
            print('Notifying....')
            cond.notify()
            print('Let me finish first')
    
    # Main function
    async def main(loop):
        t1 = loop.create_task(func1())
        t2 = loop.create_task(func2())
        await asyncio.wait([t1, t2])
    
    if __name__ == '__main__':
        l = asyncio.get_event_loop()
        l.run_until_complete(main(l))
        l.close()
    

    这将导致:

    It's look like I will need to wait
    Notifying....
    Let me finish first
    Now it's my turn
    

    另一种方法是使用asyncio.Event

    import asyncio
    
    event = asyncio.Event()
    
    async def func1():
        print('It\'s look like I will need to wait')
        await event.wait()
        print('Now it\'s my turn')
    
    
    async def func2():
        print('Notifying....')
        event.set()
        print('Let me finish first')
    

    它将与Condition 代码示例具有相同的结果。

    【讨论】:

      猜你喜欢
      • 2016-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2016-04-12
      • 1970-01-01
      相关资源
      最近更新 更多