Perl:正确传递数组以供线程使用 [英] Perl: Correctly passing array for threads to work on
问题描述
我正在学习如何在Perl中进行线程化.我正在查看示例代码此处并略微修改了解决方案代码:
I'm learning how to do threading in Perl. I was going over the example code here and adapted the solution code slightly:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Semaphore;
my $sem = Thread::Semaphore->new(2); # max 2 threads
my @names = ("Kaku", "Tyson", "Dawkins", "Hawking", "Goswami", "Nye");
my @threads = map {
# request a thread slot, waiting if none are available:
foreach my $whiz (@names) {
$sem->down;
threads->create(\&mySubName, $whiz);
}
} @names;
sub mySubName {
return "Hello Dr. " . $_[0] . "\n";
# release slot:
$sem->up;
}
foreach my $t (@threads) {
my $hello = $t->join();
print "$hello";
}
当然,现在这已完全损坏,无法正常工作.导致此错误:
Of course, this is now completely broken and does not work. It results in this error:
C:\scripts\perl\sandbox>threaded.pl
Can't call method "join" without a package or object reference at C:\scripts\perl\sandbox\threaded.pl line 24.
Perl exited with active threads:
0 running and unjoined
9 finished and unjoined
0 running and detached
我的目标有两个:
- 强制执行任何给定时间允许的最大线程数
- 提供工作"数组以供线程使用
在原始解决方案中,我注意到0..100;
代码似乎指定了分配给线程的工作"量.但是,在我要提供一系列工作的情况下,是否还需要提供类似的东西?
In the original solution, I noticed that the 0..100;
code seems to specify the amount of 'work' given to the threads. However, in my case where I want to supply an array of work, do I still need to supply something similar?
非常欢迎任何指导和更正.
Any guidance and corrections very welcome.
推荐答案
您要将foreach
的结果存储到@threads
中,而不是threads->create
的结果中.
You're storing the result of foreach
into @threads
rather than the result of threads->create
.
即使您解决了此问题,您收集完成的线程也为时已晚.我不确定这有多大的问题,但它可能会阻止在某些系统上启动64个以上的线程. (64是程序在某些系统上一次可以拥有的最大线程数.)
Even if you fix this, you collect completed threads too late. I'm not sure how big of a problem that is, but it might prevent more than 64 threads from being started on some systems. (64 is the max number of threads a program can have at a time on some systems.)
更好的方法是重用线程.这样既解决了两个问题,又避免了重复创建线程的开销.
A better approach is to reuse your threads. This solves both of your problems and avoids the overhead of repeatedly creating threads.
use threads;
use Thread::Queue 3.01 qw( );
use constant NUM_WORKERS => 2;
sub work {
my ($job) = @_;
...
}
{
my $q = Thread::Queue->new();
for (1..NUM_WORKERS) {
async {
while (my $job = $q->dequeue()) {
work($job);
}
};
}
$q->enqueue(@names); # Can be done over time.
$q->end(); # When you're done adding.
$_->join() for threads->list();
}
这篇关于Perl:正确传递数组以供线程使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!