Мой 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
loop?Мне нужно добавить некоторые
sleep
петли в конце приложения, чтобы дать время для потоков для самоуничтожения ли?
Правильно ли я понимаю, что вы используете отдельный HTTP :: объекты ASync (копируются, а не общий, новыми нитями) для получения более одного URL за раз в потоке? – pilcrow
@pilcrow - Да, похоже. Это трата ресурсов? –
Это может быть или не быть менее экономичным или экономичным во времени, но это реальный сток на циклах программиста. :) Дизайн трудно понять, и, следовательно, возможно, чтобы изменить/расширить безопасно, потому что компоненты не кажутся совершенно правильными. – pilcrow