我的Perl腳本,需要同時運行多個線程...如何在Perl中實現信號量線程通信?
use threads ('yield', 'exit' => 'threads_only');
use threads::shared;
use strict;
use warnings;
no warnings 'threads';
use LWP::UserAgent;
use HTTP::Request;
use HTTP::Async;
use ...
...和這樣的線程需要獲得來自網絡的一些信息,所以HTTP::Async
使用。
my $request = HTTP::Request->new;
$request->protocol('HTTP/1.1');
$request->method('GET');
$request->header('User-Agent' => '...');
my $async = HTTP::Async->new(slots => 100,
timeout => REQUEST_TIMEOUT,
max_request_time => REQUEST_TIMEOUT);
但一些線程需要,只有當其他線程(S)是這麼說的來訪問網絡。
my $start = [Time::HiRes::gettimeofday()];
my @threads =();
foreach ... {
$thread = threads->create(
sub {
local $SIG{KILL} = sub { threads->exit };
my $url = shift;
if ($url ...) {
# wait for "go" signal from other threads
}
my ($response, $data);
$request->url($url);
$data = '';
$async->add($request);
while ($response = $async->wait_for_next_response) {
threads->yield();
$data .= $response->as_string;
}
if ($data ...) {
# send "go" signal to waiting threads
}
}
}, $_);
if (defined $thread) {
$thread->detach;
push (@threads, $thread);
}
}
有可能是一個或多個線程等待爲「走出去」的信號,有可能是一個或多個線程,這種「走出去」的信號可以發送。一開始信號量的狀態是「等待」,一旦變爲「去」,它將保持如此。
最後,應用程序會檢查最大運行時間。如果線程運行時間過長,則發送自終止信號。
my $running;
do {
$running = 0;
foreach my $thread (@threads) {
$running++ if $thread->is_running();
}
threads->yield();
} until (($running == 0) ||
(Time::HiRes::tv_interval($start) > MAX_RUN_TIME));
$running = 0;
foreach my $thread (@threads) {
if ($thread->is_running()) {
$thread->kill('KILL');
$running++;
}
}
threads->yield();
現在的地步。我的問題是:
我怎樣才能最有效地碼在腳本等待「信號」(見上腳本註釋)。我應該只是簡單地使用一些虛擬共享變量
sleep
循環?我需要在應用程序的末尾添加一些
sleep
循環來給時間自我毀滅的主題?
難道我理解正確的話,您使用單獨的HTTP ::異步對象(複製,不共享,通過新的線程)來獲取最多一個網址每次線程一次? – pilcrow
@pilcrow - 是的,它看起來像。浪費資源嗎? –
它可能會也可能不是更少的內存或時間效率,但它是真正的消耗程序員循環。 :)設計難以理解,因此可能安全地更改/擴展,因爲這些組件看起來不太正確。 – pilcrow