Существует ли специальный синтаксис для приостановки сопрограммы, пока не будет выполнено условие? - PullRequest
0 голосов
/ 19 января 2020

Мне нужно приостановить сопрограмму, пока не будет выполнено условие. В настоящее время у меня есть:

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

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

И код вызывающего абонента:

await awaiter

Это работает, но требует шаблонного кода. Нужен ли шаблон или есть специальный синтаксис для предиката, такой как:

await condition

, который выдаст, пока условие не станет ложным?

1 Ответ

1 голос
/ 19 января 2020

В пакете 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.

...