Multithreading Perl线程-捕获退出

Multithreading Perl线程-捕获退出,multithreading,perl,try-catch,handlers,Multithreading,Perl,Try Catch,Handlers,我有生成两个线程的代码。第一个是启动应用程序的系统命令。第二个监控程序。我是perl线程新手,所以我有几个问题 my $thr1 = threads->new(system($cmd)); sleep(FIVEMINUTES); my $thr2 = threads->new(\&check); my $rth1 = $thr1->join(); my $rth2 = $thr2->join(); 1我是否需要第二个线程来监视程序?您可以将我对&check的子

我有生成两个线程的代码。第一个是启动应用程序的系统命令。第二个监控程序。我是perl线程新手,所以我有几个问题

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

my $rth1 = $thr1->join();
my $rth2 = $thr2->join();
1我是否需要第二个线程来监视程序?您可以将我对&check的子程序调用看作是一个无限while循环,用于检查应用程序生成的文本文件。我可以这样做吗:

my $thr1 = threads->new(system($cmd));
sleep(FIVEMINUTES);
✓
2我正在试图弄清楚在我运行此代码后我的父母在做什么。所以,在我启动第1行之后,它将产生新的线程,睡眠,然后产生第二个线程,然后坐在第一个加入并等待。在第一次连接之前,它不会执行我的其余代码。这是对的还是我错了?如果我错了,那么它是如何工作的

3我的第一个线程启动应用程序的线程可能会意外终止。当这种情况发生时,我无法捕捉到它并杀死线程。它只是说: 线程1异常终止:在myScript.pl第109行调用了未定义的子例程&main::65280。然后挂在那里

我该怎么做才能让它结束其他线程?我需要它在程序结束前发送一封电子邮件,我可以通过调用和发送我制作的另一个子程序来完成


谢谢,Perl中的多线程有点难处理,我建议改用fork命令。我会尽力回答你的问题

1在我看来,这里应该使用两个线程/进程,因为您需要异步检查数据

你的父母的工作和你描述的一模一样

3线程挂起的原因可能是您从未终止第二个线程。你说这是一个无限循环,有退出条件吗?

首先

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

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

my $thr1 = async { system($cmd) };
你不需要开始第三个线程。正如您所怀疑的,主线程和一个执行系统就足够了

如果命令在不到五分钟内完成执行,该怎么办?下面用一个信号代替睡眠

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();

在2004-2006年,我遇到了同样的挑战,在Winblows上24/7运行perl应用程序。。。唯一有效的方法是使用磁盘上的xml状态文件来传达系统每个组件的状态。。。并且确保如果线程被使用,那么在一个闭包代码块中发生的每个stat文件处理{}big gotcha应用程序在100台机器上24/7运行了至少3年没有错误。。。 如果您使用的是类Unix操作系统,我建议您使用forks和进程间通信。
使用cpan模块,不要重新发明轮子。

我不知道如何使用fork,但我会看一看。3是的,有,但只有当我的应用程序没有突然退出时才设置,而它经常退出。因此,我需要thread2注意到我的另一个线程意外死亡。我不知道该怎么做。也不确定发生这种情况时$thr1的值是多少。@dakillakan,这不是线程的错误。当threads->create没有给出代码引用,而是一个标量/字符串时,该消息将自毁,它将使用该字符串作为子例程名称。当系统命令退出时,它返回一个错误代码。您的问题源于将此错误代码65280用作子例程名称。你需要把它放在一个sub里,就像ikegami在他的回答中所说的那样。如果在windows上…使用linux虚拟机:为什么我需要sub在那里?异步做什么?谢谢:因为这就是threads->new的用法。在创建线程之前,您正在执行一个系统,并且您让线程执行一个由系统编号的结果命名的子例程。//async{system$cmd}与threads->newsub{system$cmd}是一样的,就像我说的。