如何在perl中运行并发线程?

时间:2010-06-22 16:07:25

标签: perl multithreading

以下似乎并不像我预期的那样在并发线程中运行,而是每个进程都会阻塞直到它完成:

my @arr = (1,2,3,4);
foreach (@arr) {
   threads->new(\&doSomething, $_)->join;
}

sub doSomething {
    my $thread = shift;
    print "thread $thread\n";
    sleep(5);
}

换句话说,它似乎与非线程版本执行相同:

my @arr = (1,2,3,4);
foreach (@arr) {
   doSomething($_);
}

我正在运行ActivePerl v5.10.1 mswin32-x86-multi-thread

如何在perl中运行并发线程?

6 个答案:

答案 0 :(得分:13)

请参阅perldoc threads

问题是在线程上调用join()等待它完成。你想生成线程然后加入,而不是作为一个操作生成/加入。

进一步了解perldoc threads说:

  

threads->列表()

     

threads->列表(线程::全部)

     

threads->列表(线程::运行)

     

<强> threads-&GT;列表(线程::加入)

     

没有参数(或使用threads :: all)   并在列表上下文中返回一个列表   所有未加入的,非独立的   线程对象。在标量上下文中,   返回相同的计数。

     

使用true参数(使用threads :: running),   返回所有未加入的列表,   非分离的线程对象   仍在运行。

     

使用false参数(使用threads :: joinable),返回已完成运行的所有未连接,未分离的线程对象的列表(即,对于 - > gt; join()将不会阻止)。

你可以使用它来循环和列出线程,在可能的情况下加入,直到所有线程都完成(并且你可能想要一个上限来等待你杀死它们并中止的时间)

答案 1 :(得分:13)

你必须加入之后,而不是在创建它们时加入:

my @arr = (1,2,3,4);
my @threads;
foreach (@arr) {
   push @threads, threads->new(\&doSomething, $_);
}
foreach (@threads) {
   $_->join();
}

答案 2 :(得分:3)

join(不仅在Perl中)导致调用线程等待另一个线程完成。所以你的例子生成线程,等待它完成,然后产生另一个线程,所以你会得到没有产生线程的印象。

答案 3 :(得分:3)

如果你不关心线程产生的输出,你可以在线程上使用 - &gt; detach()。

我的@arr =(1,2,3,4); 我的@threads; foreach(@arr){
   我的$ t = threads-&gt; new(\&amp; doSomething,$ _);    $叔&GT;分离(); }

线程完成后,它将被回收,您无需在其上调用join()。

这个模型很适合创建工蜂,你不需要向你报告。

答案 4 :(得分:1)

产生所有主题后,您必须致电join

perl -mthreads -le'$_->join for map threads->new(sub{print"Thread $_";sleep(2)}),1..4'

答案 5 :(得分:0)

my @arr = (1,2,3,4);
my @threads;
foreach (@arr) {
   push @threads, threads->new(\&doSomething, $_);
}
foreach (@threads) {
   $_->join();
}

上面的代码工作规模很小。但是如果你有几十个或更多线程,你的操作系统就会停止运行。