コンテキスト マネージャーからデーモン スレッドを開始しています。デーモン スレッドは毎秒ハートビートを送信することになっていますが、スレッド内で実行されているためです。したがって、例外が発生してもコンテキスト マネージャーは終了しません。ハートビートが停止したときにコンテキストマネージャーで例外を発生させるにはどうすればよいですか?
リーリーこの例を見つけるのに苦労しています。
###ご協力いただきありがとうございます!更新
投稿したコードとの一貫性を高めるためにコードを変更しました。しかし:###指定したコードには一貫性がありません:
heartbeat_task には、設定されている場合は関数が返されるイベントが渡されます。ただし、これは with plc():
を使用して作成された関数 main
内のコンテキスト マネージャーが終了する場合にのみ設定され、実際には設定されません。 heartbeat_task
によってスローされた例外を強制的にコンテキスト マネージャーを終了させ、関数 plc
でキャッチしたい場合は、stop_event.set()
を呼び出すのがポイントです。 ?定義上、例外により heartbeat_task
が存在しなくなった場合にのみここに到達するとしたらどうなるでしょうか?
したがって、例外がスローされるまで
を無期限に実行するか (その場合、「停止」イベントには意味がありません)、または、何らかの条件が存在するときに停止できるようにする必要があります。 heartbeat_task
ですが、そのためのコードはありません。デモンストレーションの目的で、main
が stop_event
イベントにアクセスし、特定の状況下でそれを設定すると仮定します。それ以外の場合は、heartbeat_task
が実行されていないことを検出するまで実行されます。これは、おそらく例外が発生したためです (無限ループが実行されています。停止イベントがまだ設定されていない場合、どうやって終了できるでしょうか?) )。残りは、コンテキスト マネージャーを使用する必要がある理由です。後ほど代替案を提案させていただきます。
マルチスレッド プールを使用する場合 (プールから 1 つのスレッドだけが必要です)、プールに送信されたタスクによってスローされた例外をメインスレッドが簡単にキャッチできるようになります。 .apply_async
multiprocessing.pool.asyncresult
インスタンスを返し、今後の完了を示します。このインスタンスで get
メソッドが呼び出されると、ヘルパー関数 (heartbeat_task) から戻り値を取得したり、ヘルパー関数によってスローされた例外を再発生したりできます。ただし、
wait メソッドを使用して、送信されたタスクの完了または経過時間を待つこともできます。次に、
ready メソッドを使用して、5 秒待機した後に送信されたタスクが実際に完了したかどうか (例外または戻りにより) をテストできます。タスクがまだ実行中の場合は、タスクを停止するように指示できます。このデモでは、約 7 秒後にタスクに例外をスローさせます:
リーリー
印刷:
リーリー
コンテキスト マネージャーを使用する代わりの方法
リーリー
以上がコンテキストマネージャーとデーモンスレッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。