私の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);
}
}
は「行く」信号のためのを待っ一つ以上のスレッドがあるかもしれませんし、そのような「行く」信号がを送ることができます一つ以上ののスレッドがあるかもしれません。最初にセマフォーのステータスは "wait"になり、 "go"に変わると、セマフォーはそのままになります。
最後に、アプリは最大実行時間をチェックします。スレッドが長時間実行されると、自己終了信号が送信されます。ポイントに今
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
ループを追加する必要がありますか?
は、私はあなたが最大1つのURLを取得するために別のHTTP ::非同期オブジェクト(新しいスレッドによって、共有されていない、コピーされた)を使用していることを正しく理解しています....このような何かを試してみてくださいスレッドごとに一度に? – pilcrow
@pilcrow - そうですね。資源の無駄ですか? –
メモリや時間効率はそれほど悪くないかもしれませんが、プログラマーサイクルでは本当になくなります。 :)デザインは理解しにくいので、コンポーネントが正しく見えないので、おそらく安全に変更/拡張することができます。 – pilcrow