代码之家  ›  专栏  ›  技术社区  ›  jackal

perl主程序永远等待

  •  3
  • jackal  · 技术社区  · 7 年前

    我对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 回复  |  直到 7 年前
        1
  •  7
  •   Dave Mitchell    7 年前

    这似乎是perl中的一个bug,在版本5.14.0中已修复。如果您确实无法安装较新的perl(除了系统perl之外),那么请尝试避免使用$tee共享文件句柄,这正是导致主线程挂起的原因。

    此外,等待子线程完成的代码使用了一个活动的CPU循环,这将消耗大量CPU。如果您只想等待所有子线程完成,请执行以下操作

    my @threads;
    ...
    for ... {
         push @threads, async { ... }
    }
    ...
    $_->join for @threads;
    
        2
  •  3
  •   user149341 user149341    7 年前

    我对perl[]比较陌生,我使用了线程。

    这是你的问题。

    Perl线程是 奇怪的 .他们有许多意外和不良行为;特别是,大多数变量无法在线程之间安全共享,一些模块根本不支持在线程环境中使用。引用 the threads documentation :

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

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

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