我正在编写一个简单的Perl脚本,它应该同时运行其他Perl脚本。我不知道如何使主程序等待运行线程。由于许多原因,睡眠不是一个合适的解决方案。这是我的“主要”脚本:
#!/usr/bin/perl
use threads;
main:
{
if ($#ARGV == -1) { usage(); exit(1); }
my $hostname = $ARGV[0];
my $thrssh = threads ->create(\&ssh, $hostname);
my $thrdns = threads ->create(\&dns, $hostname);
my $thrping = threads ->create(\&ping, $hostname);
my $thrsmtp = threads ->create(\&smtp, $hostname);
my $thrproxy = threads ->create(\&proxy, $hostname);
}
sub ssh {
threads->detach();
my $hostname = @_;
#print "SSH\n";
#LAUNCH SSH SCRIPT
}
#OTHER SUBROUTINES...
sub proxy {
threads->detach();
my $hostname = @_;
#print "PROXY\n";
#LAUNCH PROXY SCRIPT
}
如果我尝试运行这个脚本,我可以注意到的第一件事是打印是“顺序的”,我认为文本搞砸了,但也许打印是独家我不知道。主要问题是最后两个子程序没有时间执行。
SSH
DNS
PING
Perl exited with active threads:
2 running and unjoined
0 finished and unjoined
0 running and detached
如果我使用 join 而不是 detach ,子例程将变为“顺序”,例如,如果我在子ssh中放入休眠,则其他线程将在启动之前等待。我希望它们是并行的,并且主要程序只在所有线程完成时才关闭,任何帮助?
我实际上有另一个问题,如果我应该在foreach cicle中运行多个线程,那么我应该加入它们?即:
my $thrssh;
foreach $mynode ($nodeset->get_nodelist) {
#...
$thrssh = threads ->create(\&ssh, $port, $hostname);
#...
}
$thssh->join();
是吗?
答案 0 :(得分:9)
在完成所有线程之后,您需要join
所有线程。如果您不想在线程仍在运行时退出解释器,请不要detatch
。
...
my $thrssh = threads ->create(\&ssh, $hostname);
my $thrdns = threads ->create(\&dns, $hostname);
...
$thrssh->join();
$thrdns->join();
...
关于你的编辑:不,这不对。您需要保留对您创建的每个线程的引用,否则您无法加入它们。
做类似的事情:
my @thrs;
foreach $mynode ($nodeset->get_nodelist) {
#...
$thrssh = threads ->create(\&ssh, $port, $hostname);
push @thrs, $thrssh;
#...
}
$_->join() for @thrs;