2

我有产生两个线程的代码。第一个是启动应用程序的系统命令。第二个监视程序。我是 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。” 然后挂在那里。

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

谢谢

4

3 回答 3

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();
于 2013-06-21T19:28:57.913 回答
1

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

于 2013-06-21T19:37:17.313 回答
0

Perl 中的多线程有点难以处理,我建议改用 fork() 命令。我将尽我所能回答您的问题。

1)在我看来,两个线程/进程是要走的路,因为你需要异步检查你的数据。

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

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

于 2013-06-21T19:07:38.677 回答