Dir*_*uin 2 perl multithreading
我正在学习如何在Perl中进行线程化.我在这里查看示例代码并稍微调整了解决方案代码:
#!/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";
}
Run Code Online (Sandbox Code Playgroud)
当然,现在这已完全打破,不起作用.它导致此错误:
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
Run Code Online (Sandbox Code Playgroud)
我的目标是双重的:
在原始解决方案中,我注意到0..100;代码似乎指定了给予线程的"工作量".但是,在我想提供一系列工作的情况下,我还需要提供类似的东西吗?
任何指导和更正都非常受欢迎.
你存储的结果foreach为@threads,而不是结果threads->create.
即使您解决了这个问题,也会过早收集完成的线程.我不确定问题有多大,但它可能会阻止在某些系统上启动64个以上的线程.(64是程序在某些系统上一次可以拥有的最大线程数.)
更好的方法是重用您的线程.这解决了您的两个问题,并避免了重复创建线程的开销.
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();
}
Run Code Online (Sandbox Code Playgroud)