asyncioイベントループが次の意味でアイドルになったときに検出できるプログラミングパターンがありますか?私の実行パスは、asyncio.gather()を使用して複雑な方法で分岐するとしますが、各ブランチが最終的にはソケットやサブプロセスなどのアイドルコルーチンを待っていることを知っています。私はこれらのコルーチンが実際には得られないことを知っていると言えば、イベントループは実行可能なPythonコードを実行しますが、最終的にはそれらのアイドルコルーチンを待つだけです。このような状態を検出してループを停止するプログラム的な方法はありますか?アイドルasyncioイベントループを検出する
答えて
「アイドル」と呼ばれるものは、「IOまたはタイムアウトを待っている」と正確に記述することができます。正しく書かれたasyncioコードでは、という内容のがループしていることを検出する必要はありません。ループはその仕事をしており、asyncio.gather
,asyncio.wait
、loop.run_until_complete
のようなツール適切なタイミングで終了するようにしてください。しかし、物事はいつも完璧というわけではありません。あなたが本当にそれをしたいのなら、確かに可能です。
イベントループの各ステップで、実行準備が整っているタスクをチェックします。もしあれば、そのステップが呼び出されます。タスクがもう準備できなくなると、イベントループはIOイベントまたは最も早いタイムアウトのいずれか早い方を待つ。重要なことは、実行中のタスクが常にIOを待つことよりも優先されることです。したがって、タスクが準備できていない場合を検出するために、すぐに発火することが知られているダミーIOイベントをスケジュールすることができます。
以下コルーチンは、このようなイベントを設定し、トリガすることを待つ:
import socket, asyncio
async def detect_iowait():
loop = asyncio.get_event_loop()
rsock, wsock = socket.socketpair()
wsock.close()
await loop.sock_recv(rsock, 1)
rsock.close()
それが1つのソケットから読み出しが他のソケットに書き込まれたデータを返すsocket pairを設定します。これはただちにソケットの1つを閉じます。したがって、もう一方の読み取りからすぐに空のbytearrayとして表されるEOFが返されます。そのソケットからの読み取りを待つのは基本的に非ブロックですが、asyncio
はそのことを知らないので、IO待機リストにソケットを配置します。上記のように、実行可能なタスクが存在しなくなると、asyncioはIOを待機し、detect_iowait
はソケットの読み込みと終了を待ちます。したがって、detect_iowait()
が待機中であることを待機しています。 detect_iowait()
を使用しています
テストコードは次のようになります。
# stop loop.run_forever once iowait is detected
async def stop_on_iowait():
await detect_iowait()
print('iowait detected, stopping!')
asyncio.get_event_loop().stop()
# a dummy calculation coroutine, emulating your execution path
async def calc(n):
print('calc %d start' % n)
async def noop():
pass
for i in range(n):
await noop()
print('calc %d end' % n)
# coroutine that waits on IO forever, also (ab)using a socket pair,
# this time creating a socket whose recv will never complete
async def io_forever():
loop = asyncio.get_event_loop()
sock, _ = socket.socketpair()
sock.setblocking(False)
await loop.sock_recv(sock, 1)
loop = asyncio.get_event_loop()
for t in calc(1000), calc(10000), calc(100000), io_forever():
loop.create_task(t)
loop.create_task(stop_on_iowait())
loop.run_forever()
- 1. asyncioイベントループにジョブを提出する
- 2. asyncioイベントループの監視
- 3. Asyncio RuntimeError:イベントループが終了しました
- 4. VBアイドル時間を検出する
- 5. Windows phone 7 Appアイドル検出
- 6. asyncioイベントループを使用してtornado.testing.AsyncTestCaseを実行します。
- 7. asyncio:新しいイベントループを作成できません
- 8. Pythonで既存のasyncioイベントループを使用してREST APIを実装する
- 9. アイドル状態検出silverlight 4アプリケーション
- 10. ブーストASIOサーバー - アイドル接続の検出
- 11. asyncioイベントループでconcurrent.futuresを使用できないのはなぜですか?それはasyncio持っていることを述べasyncioドキュメントから
- 12. Pythonを使用してアイドル時間を検出する
- 13. asyncioイベントループの長さはどのように測定できますか?
- 14. タブ間でもアイドル時間を検出できますか?
- 15. すべてのワークフローシーケンスがアイドル状態であることを検出します。
- 16. カスタムPython asyncioイベントループの実装方法を知るにはどうすればよいですか?
- 17. 手動でasyncioイベントループをオンに切り替える方法はありますか
- 18. Python 3.5 asyncioは、異なるスレッドの同期コードからイベントループでcoroutineを実行します。
- 19. Eclipse RCPアプリケーション - アプリケーションがアイドル状態のときの検出方法
- 20. イベントループ
- 21. Python asyncioイベントループ。非同期タスクを完了した後、ループを永遠に実行してください。
- 22. asyncio pythonで関数呼び出しを実行する方法
- 23. Javascriptのアイドル状態を検出するにはどうすればよいですか?
- 24. CometProcessor Endイベントループ
- 25. アニメーションのQStateMachineイベントループ
- 26. JavaScriptスタック、キュー、イベントループ?
- 27. イベントループ対マルチスレッドブロックIO
- 28. NodeJSイベントループのポーリングフェーズ
- 29. ThreadPoolにアイドル状態のスレッドがあるかどうかを検出する方法は?
- 30. Winformsアプリケーションを検出する方法は一定の時間アイドル状態になっています
は、なぜあなたはループを停止する必要がありますか?ソケットジョブまたはサブプロセスジョブが完了する前に停止すると、結果をコルーチンに伝播することができません。 –
これらの決して譲歩しないコルーチンには副作用があり、これを実行したい。しかし、それらのすべてが実行されたら、私はアプリケーションを停止したい。これは、アプリケーションの特定のユースケースのシナリオです。実行パスは単に中断されます。 – azag0
yyyyyで検出したくないこれらのコルーチンを含む、再現可能なコードをいくつか提供できますか? –