waitpid とタイムアウトに関する多くの質問があることは承知していますが、それらはすべて、アラーム ハンドラ内から子を殺すことでこれをカバーしています。
それは私が望むものではありません。プロセスを実行し続けたいのですが、waitpid からディスパッチします。
私が解決しようとしている根底にある問題は、キューを処理するメイン ループを持つデーモン プロセスです。タスクは一度に 1 つずつ処理されます。
タスクがハングすると、メイン ループ全体がハングします。これを回避することは、当然の選択のようfork()
に思えました。waitpid
それでもタスクがハングすると、ループがハングします。
waitpid をまったく使用しない回避策を考えることができますが、ハングする可能性のあるタスクと並行して一度に 1 つのタスクを処理したいので、実行中のプロセスを別の方法で追跡する必要があります。
タスクを強制終了することもできますが、正確に何が問題なのかを調べるために実行したいと思います。一部のデバッグ情報をダンプする kill ハンドラーも可能です。
とにかく、その問題を解決する最も便利な方法は、可能であれば waitpid をタイムアウトにすることです。
編集:
これは私が fork() と waitpid を使用した方法であり、子の意味がより明確になる可能性があります。
my $pid = fork();
if ($pid == 0){
# i am the child and i dont want to die
}
elsif ($pid > 0) {
waitpid $pid, 0;
# i am the parent and i dont want to wait longer than $timeout
# for the child to exit
}
else {
die "Could not fork()";
}
編集:
waitpid WNOHANG を使用すると、私が望むことができます。この使用法は良い習慣ですか、それとも別の方法で行いますか?
use strict;
use warnings;
use 5.012;
use POSIX ':sys_wait_h';
my $pid = fork();
if ($pid == 0){
say "child will sleep";
sleep 20;
say "child slept";
}
else {
my $time = 10;
my $status;
do {
sleep 1;
$status = waitpid -1, WNOHANG;
$time--;
} while ($time && not $status );
say "bye";
}