我很新的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