2

2 つのスレッドを生成するコードがあります。1 つ目は、アプリケーションを起動するシステム コマンドです。2 つ目は、プログラムを監視します。私はperlスレッドが初めてなので、いくつか質問があります...

my $thr1 = threads->new(system($cmd));
sleep(FIVEMINUTES);
my $thr2 = threads->new(\&check);

my $rth1 = $thr1->join();
my $rth2 = $thr2->join();

1) プログラムを監視するために 2 つ目のスレッドが必要ですか? &check への私のサブルーチン呼び出しは、アプリケーションが生成するものについてテキスト ファイルをチェックする無限の while ループと考えることができます。これを行うことができますか:

my $thr1 = threads->new(system($cmd));
sleep(FIVEMINUTES);
✓

2) このコードを実行した後、親が何をしているのかを把握しようとしています。したがって、1 行目を起動すると、新しいスレッドが生成され、スリープ状態になり、次に 2 番目のスレッドが生成され、最初の結合に座って待機します。その最初の結合で結合するまで、残りのコードは実行されません。これは正しいですか、それとも間違っていますか? 私が間違っている場合、それはどのように機能しますか?

3)アプリケーションを起動する最初のスレッドが予期せず強制終了される可能性があります。これが発生した場合、それをキャッチしてスレッドを強制終了するものは何もありません。「スレッド 1 が異常終了しました: 未定義のサブルーチン &main::65280 が myScript.pl 行 109 で呼び出されました。」そしてそこにぶら下がります。

他のスレッドを終了させるにはどうすればよいですか? プログラムが終了する前に電子メールを送信するためにも必要です。これは、 &email (私が作成した別のサブルーチン) を呼び出すだけで実行できます。

ありがとう

4

3 に答える 3

4

初めに、

my $thr1 = threads->new(system($cmd));

する必要があります

my $thr1 = threads->new(sub { system($cmd) });

または単に

my $thr1 = async { system($cmd) };

3 番目のスレッドを開始する必要はありません。ご想像のとおり、メイン スレッドと実行中のスレッドでsystem十分です。


コマンドの実行が 5 分以内に終了した場合はどうなりますか? 以下は、スリープをシグナルに置き換えます。

use threads;
use threads::shared;

my $done :shared = 0;

my $thr1 = async {
   system($cmd);

   lock($done);
   $done = 1;
   cond_signal($done);
};

{ # Wait up to $timeout for the thread to end.
   lock($done);
   my $timeout = time() + 5*60;
   1 while !$done && cond_timedwait($done, $timeout);
   if (!$done) {
      ... there was a timeout ...
   }
}

$thr1->join();
于 2013-06-21T19:28:57.913 に答える
1

2004 年から 2006 年にかけて、Winblows で 24 時間年中無休で perl アプリを実行するという同じ課題がありました...唯一の有効な方法は、ディスク上の xml 状態ファイルを使用して、システムの各コンポーネントの状態を通信することでした...スレッドはすべての stat ファイル処理がクロージャ コード ブロック内で発生するたびに使用されます{}(大きな落とし穴) アプリは 100 台のマシンで 24 時間 365 日エラーなしで少なくとも 3 年間実行されました ... Unix ライクな OS を使用している場合は、フォークを使用することをお勧めしますそしてプロセス間通信。cpan モジュールを使用し、車輪を再発明しないでください。

于 2013-06-21T19:37:17.313 に答える