Проблема с ожиданием события в Curio - PullRequest
3 голосов
/ 07 июня 2019

Я использую curio для реализации механизма двух задач, которые взаимодействуют с использованием объекта curio.Event.Первая задача (называемая action()) запускается первой, а awaits событие, которое нужно установить.Вторая задача (называемая setter()) запускается после первой и устанавливает событие.

Код выглядит следующим образом:

import curio

evt = curio.Event()


async def action():
    await evt.wait()
    print('Performing action')


async def setter():
    await evt.set()
    print('Event set')


async def run():
    task = await curio.spawn(action())
    await setter()
    print('Finished run')
    await task.wait()


curio.run(run())

Вывод следующий:

Event set
Finished run
Performing action

Это означает, что print('Performing action') выполняется ПОСЛЕ print('Finished run'), и это то, что я пытаюсь предотвратить - я ожидал, что вызов await evt.set() также вызовет всех его официантов, и run()не будет продолжаться до тех пор, пока не будут вызваны все официанты, что означает, что action() будет продолжено ДО выполнения print('Finished run').Вот что мне хотелось бы получить:

Event set
Performing action
Finished run

Что я не так делаю?Есть ли способ изменить это поведение?Я хотел бы иметь больше контроля над порядком исполнения.

Спасибо

1 Ответ

1 голос
/ 07 июня 2019

Установка Event - это способ сообщить о том, что что-то произошло: он, как вы уже отметили, не обеспечивает вызов официантов.

Если вы хотите сообщить о завершении выполнения после выполненного действия, вы должны сообщить об этом после ожидания действия:

async def run():
    task = await curio.spawn(action())
    await setter()
    await task.wait()  # await action been performed
    print('Finished run')  # and only after that reporting run() is done

Если вы хотите заблокировать выполнение run(), пока что-то не произошло, вы можете сделать это с другим событием wait(), которое должно быть set(), когда это что-то произошло:

import curio

evt = curio.Event()
evt2 = curio.Event()


async def action():
    await evt.wait()
    print('Performing action')
    await evt2.set()
    print('Event 2 set')


async def setter():
    await evt.set()
    print('Event set')


async def run():
    task = await curio.spawn(action())
    await setter()    
    await evt2.wait()
    print('Finished run')
    await task.wait()


curio.run(run())

Res:

Event set
Performing action
Event 2 set
Finished run
...