如果我启动多个线程,Perl的线程连接方法是否等待第一个线程完成?

时间:2011-12-07 16:23:00

标签: multithreading perl join parallel-processing

     foreach $name (@project_list)
     {
               # a thread is created for each project
               my $t = threads->new(\&do_work, $name);
               push(@threads, $t);
     } 

    foreach (@threads) {
     my $thrd = $_->join;
     print "Thread $thrd done\n";
    }

    sub do_work {
     # execute some commands here...
    }

project_list是40个项目的列表。当我为每个项目生成一个线程时,join方法是否会等待第一个线程完成,然后转移到下一个线程,依此类推?

如果是这种情况,那么可以避免它吗?我的意思是一些线程会比其他线程更快完成,所以为什么要等待?

如果需要更多信息,请与我们联系。 谢谢。

3 个答案:

答案 0 :(得分:5)

$_->join等待$_指定的线程完成。由于你按顺序推送它们,并且foreach按顺序遍历列表,是的,你将首先等待第一个线程。

但这并不重要,因为您正在等待所有线程完成。如果你先等待最快的终结者或最慢的终结者并不重要 - 无论如何你都会等待所有人。

答案 1 :(得分:3)

为什么要等?这取决于后处理步骤的范围。

如果后处理步骤需要在开始工作之前完成所有线程,那么等待单个线程是不可避免的。

如果后处理步骤特定于每个线程的结果,则应该可以使线程的后处理部分本身。

在这两种情况下,$_->join foreach @threads;都是可行的方法。


如果不需要等待线程完成,请使用detach命令而不是join。但是,线程可能返回的任何结果都将被丢弃。

答案 2 :(得分:0)

主线程必须在所有线程的持续时间内存活,因此您需要知道它们何时完成。可以完成队列或信号量。信号量是最简单的:

use Thread::Semaphore;

my $S = Thread::Semaphore->new();


foreach $name (@project_list)
{
    # a thread is created for each project
    my $t = threads->new(\&do_work, $name);
    $S->down_force();                        # take one for each thread
} 

$S->down();                # this blocks until worker threads release one each
print "Thread $thrd done\n";


sub do_work {
    # execute some commands here...
    $S->up();             # here the worker gives one back when done.
}