Perl线程 - 捕获退出

时间:2013-06-21 18:52:40

标签: 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视为无限循环,它会检查文本文件以查找应用程序生成的内容。我可以这样做:

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

2)我试图弄清楚我的父母在运行此代码后正在做什么。因此,在我启动第1行之后,它将生成该新线程,休眠,然后生成第二个线程,然后坐在第一个连接并等待。在它加入第一个连接之前,它不会执行我的其余代码。这是正确的还是我错了?如果我错了,那它是如何运作的?

3)启动应用程序的第一个线程可能会被意外杀死。当这种情况发生时,我没有什么可以抓住它并杀死线程。它只是说: “线程1异常终止:在myScript.pl第109行调用未定义的子程序& main :: 65280。”然后挂在那里。

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

由于

3 个答案:

答案 0 :(得分:4)

首先,

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

应该是

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

或只是

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

您不需要启动第三个线程。如您所料,主线程和执行system的主线程就足够了。


如果命令在不到五分钟内完成执行该怎么办?以下内容用信号替换睡眠。

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

答案 1 :(得分:1)

2004-2006我在Winblows上运行24/7 perl应用程序遇到了同样的挑战......唯一的工作方法是在磁盘上使用xml状态文件来传达系统中每个组件的状态......确保在封闭代码块{}内发生的每个统计文件处理是否使用了线程(大问题)该应用程序在100台机器上至少运行3年,每天24小时没有错误... 如果您使用的是类Unix操作系统,我建议使用分支和进程间通信。 使用cpan模块,不要重新发明轮子..

答案 2 :(得分:0)

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

1)在我看来,这里有两个线程/进程,因为你需要检查异步检查数据。

2)您的父母完全按照您的描述工作。

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