無限に繰り返される可能性のあるプログラムをタイムアウトする方法

無限に繰り返される可能性のあるプログラムをタイムアウトする方法

無限ループを含むと思われるプログラムや実行に時間がかかる可能性がある他のコードを実行しているとします。私はLinuxで次のことができることを知っています。

timeout 1 ./program

プログラムに1秒のタイムアウトを提供します。しかし、私が正しく理解しているなら、これはプログラムに「SIGTERM」信号だけを送ることです。プログラムはこれを無視できます。とにかく、プログラムが1秒後に停止するようにするより安全な方法はありますか?

私が考えた1つの解決策は、次のようにbashとtimeout bashでプログラムを実行することです。

timeout 1 bash -c './program'

その後、1秒後にbashが終了するため、実行中のプログラムも終了します。これは良い解決策ですか?

ベストアンサー1

それは実際に「安全」とは何を意味するかによって異なります。プロセスを終了するには2つのオプションがあります。

  • 慎重にプロセス自体のシャットダウンを要求します(例:SIGTERMを使用)。
  • カーネルに強制的に終了するように無意識のうちに要求しますkill -9

ほとんどの場合、プロセスを終了する最もクリーンで「最も安全な」方法は、SIGTERMを使用して慎重に要求することです。これは、基本的にプログラムがSIGTERMをすべての子プロセスに伝播してプロセスツリー全体をクリーンアップするためです。プロセスを終了すると、実行していたタスク(バッファーフラッシュなど)を完全に終了する時間があるため、より良いです。

プロセスを強制終了するときに子プロセスが必ずしも(またはデフォルトで)終了するわけではありません。孤児を残す傾向があります。また、ファイルが破損しやすく、一般的に混乱を引き起こします。したがって、kill -9クリーンアップのためにforcekill()を自動的に使用しないでください。


Bashスクリプトは整理するのが特に面倒です。デフォルトでは、SIGTERMを子プロセスに伝播し、子プロセスが終了するのを待ちます。何らかの理由でSIGTERMをbashスクリプトに送信しましたが、終了しないと、kill -9孤児はほぼ確実に遅れます。

強制的に殺すには強制的に殺すスクリプトが必要ですそして子供たち全員を強制的に殺すこれはしばしば混乱するため、自動操作にはお勧めできません。

幸いなことにtimeout、子プロセスの問題を知っています。要求時にプロセスツリー全体を消去します。

timeout -s 9 20 myscript

すべての子プロセスを強制的に終了します。これはまだコマンドを閉じる「汚い」方法です。なぜなら、コマンドはそれ自体が適切にクリーンアップする機会がなく、ファイルを破損する可能性があるからです。

おすすめ記事