我很新的perl(也是编程),并且在过去的几个星期里在线程上玩耍,到目前为止我明白使用它们来执行一些类似的并行任务是不鼓励的 - 内存消耗如果你的线程数量取决于某些输入值,并且仅仅限制这个数字并进行一些临时连接似乎非常愚蠢,那么它是不可控制的。 所以我试图欺骗线程队列通过,随后分离这些线程(和没有实际加入他们)返回我一些价值观 - 在这里与平行平的例子:perl线程自我分离
#!/usr/bin/perl
#
use strict;
use warnings;
use threads;
use NetAddr::IP;
use Net::Ping;
use Thread::Queue;
use Thread::Semaphore;
########## get my IPs from CIDR-notation #############
my @ips;
for my $cidr (@ARGV) {
my $n = NetAddr::IP->new($cidr);
foreach (@{ $n->hostenumref }) {
push @ips, (split('/', $_))[0];
}
}
my $ping = Net::Ping->new("icmp");
my $pq = Thread::Queue->new(@ips, undef); # ping-worker-queue
my $rq = Thread::Queue->new(); # response queue
my $semaphore = Thread::Semaphore->new(100); # I hoped this may be usefull to limit # of concurrent threads
while (my $phost = $pq->dequeue()) {
$semaphore->down();
threads->create({ 'stack_size' => 32 * 4096 }, \&ping_th, $phost);
}
sub ping_th {
$rq->enqueue($_[0]) if $ping->ping($_[0], 1);
$semaphore->up();
threads->detach();
}
$rq->enqueue(undef);
while (my $alive_ip = $rq->dequeue()) {
print $alive_ip, "\n";
}
我找不到一个完全关于threads-> detach()应该如何在一个线程化子程序中工作,并认为这可能会奏效......并且它的确如此 - 如果我在主程序(线程)中做了一些延伸它一生的工作(睡眠很好) ,因此所有分离的线程完成并将它们的部分排入我的$ rq,否则它将运行一些线程将其结果收集到队列并退出,并出现如下警告:
Perl exited with active threads:
5 running and unjoined
0 finished and unjoined
0 running and detached
让主程序“睡眠”一段时间再次显得很愚蠢 - 是否没有办法使线程完成它们的工作,并在实际线程 - > detach()调用之后进行分离? 到目前为止,我的猜测是一旦创建线程就会应用子线程中的threads-> detach(),所以这不是方法。 我用CentOS很好的旧v5.10.1试了一下。应该用现代v5.16还是v5.18(usethreads-compiled)进行更改?
顺便说一句,为什么你想分离线程? – 2014-10-29 12:08:55
我有些困惑。如果你想让线程更快分离,请尽快调用'threads-> detach()'(并不是说我明白为什么要分离线程开始)。此外,你可能会产生少量的工作线程,让他们出列,而不是每个排队的元素产生一个线程。这样你就可以拥有更少的线程,并且可以推迟加入直到工作完成(例如,等待直到'!$ pq-> pending()',或者只要加入队列中的所有线程就加入池中的所有线程工作) – Hasturkun 2014-10-29 12:29:20
我并不认为detach实际上是这里工作的工具,因为你在尝试整理结果时需要等待每个线程退出前完成。 – Sobrique 2014-10-29 12:38:52