perl主程序永远等待

时间:2018-05-06 16:10:30

标签: perl

我是perl的新手,我编写了一个程序来处理一组操作系统映像上的相同操作。由于操作相同,我使用了线程。附加了该程序的缩小版本。问题是,主程序永远不会出现并等待永远。在追踪时,我看到主程序在等待" tee"命令。我有什么东西在这里搞砸了?

我在使用Perl版本5.1的CentOS 6.7上,由于许多其他依赖项,我无法继续前进:(

#!/usr/bin/perl -w
use threads;


my $tee_pid= open my $tee, "|-", "tee mylog";
my @images = ( "image1" , "image2");

foreach my $image (@images){
$_ = async { do_ops_on_image() };
sleep ( 60 );
}

while( threads->list ) {
    for my $joinable ( threads->list( threads::joinable ) ) {
        $joinable->join;
    }
}
print "All thread completed \n";
close $tee;

sub do_ops_on_image
{
  my $time = `date`;
  my $id = threads->tid();
  sleep (120) if ( $id ==2 );
  print $tee "my $id started at $time \n";
}

2 个答案:

答案 0 :(得分:7)

这似乎是在版本5.14.0中修复的perl中的错误。如果你真的无法安装更新的perl(除了系统perl),那么尽量避免$ tee共享文件句柄,这是导致主线程挂起的原因。

此外,等待子线程完成的代码使用一个活动的CPU循环,它会烧掉大量的CPU。如果您只想等到所有子线程都完成,请执行类似

的操作
my @threads;
...
for ... {
     push @threads, async { ... }
}
...
$_->join for @threads;

答案 1 :(得分:3)

  

我对perl [...]使用线程相对较新。

这是你的问题。

Perl线程很奇怪。他们有许多意想不到的不良行为;特别是,大多数变量不能在线程之间安全地共享,并且某些模块根本不支持在线程环境中使用。引用the threads documentation

  

Perl提供的“基于解释器的线程”并不是人们可能期望或希望的快速,轻量级的多任务处理系统。线程的实现方式使其易于滥用。很少有人知道如何正确使用它们或能够提供帮助。

     

官方不鼓励在perl中使用基于解释器的线程。

对于许多常见应用程序,Parallel::ForkManager模块可能是更合适的选择。