我有生成两个线程的代码。第一个是启动应用程序的系统命令。第二个监控程序。我是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(我制作的另一个子程序)来完成。
由于
答案 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)你的线程挂起的原因可能是你永远不会终止你的第二个线程。你说这是一个无限循环,有退出条件吗?