Event
trioにはEventというクラスがあり、次のメソッドがあります。
-
await wait()
:非同期関数でありset()
が呼ばれるまで待機します -
set()
:wait()
での待機を終了させます -
is_set()
: 既にset()
されていればTrueを返します
例えば次のように使えます。
import trio
async def func1(event: trio.Event):
print("func1 start")
await trio.sleep(1)
print("set event")
event.set()
await trio.sleep(1)
print("func1 done")
async def main():
async with trio.open_nursery() as nursery:
event = trio.Event()
nursery.start_soon(func1, event)
print("wait for event")
await event.wait()
print("end of nursery")
print("all end")
trio.run(main)
これは必ず次の結果になります。
wait for event
func1 start
set event
end of nursery
func1 done
all end
-
await event.wait()
はevent.set()
が呼ばれるまで待機します -
前記事を見て欲しいですが、await時は他の処理が優先され、awaitでない時はその処理が優先されます
- main関数では
await event.wait()
までawaitしてないので、それまでmain関数の処理が優先されて"wait for event"が最初のメッセージになります -
await event.wait()
時にfunc1の処理が優先されて"func1 start"を出力し、1秒後にevent.set()
されます("set event"が出力される) -
event.set()
によってawait event.wait()
の待機が終了するため、"end of nursery"が出力されます - nurseryのwithブロックは子タスクが終了するまで抜けないため、"func1 done"となってから"all end"になります
- main関数では
Eventの注意点
既にset()
されていればawait wait()
しても待機しません。
よって下記は直ちに"done"となります。
import trio
async def main():
event = trio.Event()
event.set()
await event.wait()
await event.wait()
await event.wait()
print("done")
trio.run(main)