私はThread::Pool
モジュールをperlで使用して、いくつかのperlコードを並列化しています。このプロセスにはしばらく時間がかかり、ときどきコマンドラインからSIGINT
を使用して強制終了します。そうすることで、予想通りにプログラムが突然終了します。これは、面倒な一時ファイルを残しているので、私はシグナルハンドラをインストールしたいと思います。私はこれをしました:スレッドperlとシグナルハンドラ
sub INT_Handler{
#clean up code
exit(1);
}
$SIG{'INT'} = 'INT_handler';
スレッドプールを作成し、スレッドを開始する前に。今すぐSIGINT
を送信すると、実行中のworker threadsが終了しますが、プールはすぐに次のジョブセットを処理する別のセットワーカーを起動し、実行を継続します。シグナルハンドラで終了する呼び出しがメインスレッドを終了しないのはなぜですか?プロセスの実行を停止するには何が必要ですか?
暴徒さんのコメントここ
**さらに編集**
に応じて編集私が書いた例があります。 0
と
use Thread::Pool;
sub INT_handler{
print "Handler\n";
exit(1);
}
$SIG{'INT'}='INT_handler';
sub f{
print "Started a thread " . rand(10000) . "\n";
sleep(10);
}
my $pool;
my $submit = \&f;
if (0){
$pool = Thread::Pool->new({do=>'f', workers=>5});
$submit = sub{ $pool->job; }
}
for (my $i = 0; $i < 100; $i++){ $submit->(); }
$pool->shutdown if defined $pool;
、私が期待した結果
h:57 Sep 15 16:15:19> perl tp.pl
Started a thread 3224.83224635111
Handler
けどを参照してください1
で、これは
h:57 Sep 15 16:14:56> perl tp.pl
Started a thread 5034.63673711853
Started a thread 9300.99967009486
Started a thread 1394.45532885478
Started a thread 3356.0428193687
Started a thread 1424.4741558014
などを発生し、ハンドラが入力されないと、プロセスが実行して続けます。 SIGINT
以外のシグナルでプロセスを強制終了しなければなりませんでした。ハンドラがなければ、両方のケースは単にSIGINT
を渡すと終了します。
これは[ドキュメンテーション](http://search.cpan.org/perldoc?threads#BUGS_AND_LIMITATIONS)と競合しています:「シグナルはスクリプトのメインスレッド(スレッドID = 0)によって捕捉されます。 "ワーカースレッドでシグナルが捕捉されているようなコードを分離してポストすることはできますか? – mob
@mob Ok。だから私は、信号が作業者によって捕らえられたと誤解しなければならない。私はシグナルハンドラでexitを明示的に呼び出すので、そうであると仮定しました。それでも、私が観察しているのは、死にかけているワーカースレッドと新しいワーカーが立ち上げられていることです。 –