Perl を使用して、時間のかかるプロセスまたは停止したプロセス (
system
コマンドによって生成されたプロセス) を強制終了する方法。コマンドを使用して開始されたプロセスに
system
時間がかかりすぎたり、どこかでスタックしたりするプロセスを強制終了する方法。
3 に答える
PerlFAQのセクション8には次のものが含まれています
遅いイベントをタイムアウトするにはどうすればよいですか?
perlipcのSignalsおよびCamelの「Signals」のセクションに
alarm
記載されているように、おそらくシグナルハンドラーと組み合わせて関数を使用します。代わりに、CPANから入手できるより柔軟なSys::AlarmCallモジュールを使用することもできます。この
alarm
機能は、すべてのバージョンのWindowsに実装されているわけではありません。特定のバージョンのPerlのドキュメントを確認してください。
perlipcドキュメントの「Signals」セクションには次のものが含まれています
信号処理は、Unixのタイムアウトにも使用されます。ブロック内で安全に保護されている間
eval{}
、アラーム信号をトラップするように信号ハンドラーを設定してから、数秒以内にアラーム信号を配信するようにスケジュールします。次に、ブロック操作を試してくださいeval{}
。ブロックを終了する前ではなく、完了したらアラームをクリアしてください。それが消えたら、あなたはdie
ブロックから飛び出すために使用します。次に例を示します。
my $ALARM_EXCEPTION = "alarm clock restart"; eval { local $SIG{ALRM} = sub { die $ALARM_EXCEPTION }; alarm 10; flock(FH, 2) # blocking write lock || die "cannot flock: $!"; alarm 0; }; if ($@ && $@ !~ quotemeta($ALARM_EXCEPTION)) { die }
タイムアウトしている操作がまたはの
system
場合qx
、この手法はゾンビを生成する可能性があります。これがあなたにとって重要であるならば、あなたはあなた自身fork
でそしてexec
、そして誤った子プロセスを殺す必要があるでしょう。より複雑な信号処理については、標準のPOSIXモジュールが表示される場合があります。残念ながら、これはほとんど完全に文書化されていません
t/lib/posix.t
が、Perlソースディストリビューションのファイルにはいくつかの例が含まれています。
同じスクリプト内で system() によって呼び出されたプロセスを強制終了することを期待している場合、プロセスが完了するまで system() 呼び出しは返されないため、その PID を取得したり強制終了したりする方法はありません。代わりに、fork() を使用して新しいプロセスを作成し、system() によって最初に呼び出されたプロセスを、exec() によって新しく作成されたプロセスで実行できます。fork() は子プロセスの PID を返すので、いつでも kill() で強制終了できます。
http://perldoc.perl.org/functions/fork.html
主にセキュリティ対策(ユーザー入力)として、forkとexecを使用することをお勧めします。
ただし、ユーザー入力を気にせず、システムの使用を開始したプロセスを認識している場合は、タスクリストまたはls呼び出しへのパイプを開き、grepで処理して、気になるプロセスを見つけてから、killシグナルを送信できます。それらのプロセスに。