以下似乎并不像我预期的那样在并发线程中运行,而是每个进程都会阻塞直到它完成:
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中运行并发线程?
答案 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();
}
上面的代码工作规模很小。但是如果你有几十个或更多线程,你的操作系统就会停止运行。