2016-12-11 4 views
2

Я пытаюсь создать программу, которая может подключаться к 100 URL-адресам за раз, и в зависимости от вывода каждого соединения (т. Е. Успеха в HTTP-подключении), скрипт perl переходит к функции x, или что не , Лучшее, что я мог придумать, это этот сценарий. Но я хотел бы, чтобы он подключался к 100 URL-адресам одновременно или параллельно, каждый из которых возвращал ответ (так что я должен получить 100 или около того в конце тайм-аута LWP), чтобы выяснить, что я хочу сделать дальше. Тем не менее, большинство примеров, которые я видел, имеют тенденцию делать один URL вовремя. Он может проходить через 20-30 реальных быстрых, но если кто-то не работает, именно там начинается замедление.Попытка обработки 100 запросов URL. Должен ли я использовать perl CPAN HTTP :: Async? Mojo?

use Mojo::Client; 
use Mojo::Transaction; 

my $client = Mojo::Client->new; 

my $tx = Mojo::Transaction->new_get('http://labs.kraih.com'); 
my $tx2 = Mojo::Transaction->new_get('http://mojolicious.org'); 
$tx2->req->headers->expect('100-continue'); 
$tx2->req->body('foo bar baz'); 

$client->process_all($tx, $tx2); 

print $tx->res->code; 
print $tx2->res->code; 
print $tx2->res->content->file->slurp; 

Однако он создает переменные для каждой транзакции. Если я собираюсь сделать 100 сайтов, создание $ tx1 - $ tx 100 будет болезненным.

Заранее благодарен.

+1

Это [легко] (http://stackoverflow.com/a/12168814/589924) с использованием потоков, но я хотел бы использовать [Net :: Curl :: Мульти] (Http: //search.cpan. org/perldoc? Net :: Curl :: Multi). Очень способный и очень низкий накладные расходы. – ikegami

+0

Вы можете развернуть процесс, прежде чем проверять URL столько раз, сколько ваш URL. Таким образом, каждый новый процесс будет обрабатывать свой запрос, и если процесс застопорился, вам все равно, потому что другое будет обрабатываться нормально. У вашего процесса будет переменная состояния (main или fork). Это главное, это только forks, устанавливая переменную, содержащую URL-адрес. Это вилка, она запрашивает URL-адрес. Мммм ... Похоже на темы, а? –

+1

[LWP :: Parallel] (https://metacpan.org/pod/LWP::Parallel)? Вам не нужны потоки, асинхронные ввода-вывода. – Schwern

ответ

0

Вот мое основное предложение: создать процесс для каждого URL-адреса и позволить процессу обрабатывать его независимо друг от друга. Обратите внимание, что если вам нужно регистрироваться, все процессы могут совместно использовать дескриптор файла.

#!/usr/bin/perl 

use strict;use warnings; 

my @url = ('url1','url2','url3'); 

my $pid; 
my $url_to_process; 

foreach my $url (@url) { 
    $pid = fork; #create new process. 
    unless ($pid) { 
     $url_to_process = $url; 
     last; 
    } #end loop if we are a child 
} 

unless ($pid) { 
    print "$$: $url_to_process\n"; # or do anything you like with the url 
} 
+0

Спасибо, forking работал. Я закончил использование Parallel :: ForkManager и последовал примеру, что по сути одно и то же. –

+0

[код] использовать Параллельный :: ForkManager; my $ pm = Parallel :: ForkManager-> new ($ MAX_PROCESSES); DATA_LOOP: foreach my $ data (@all_data) { # Вилки и возвращает pid для ребенка: my $ pid = $ pm-> start и next DATA_LOOP; ... выполните некоторую работу с $ данными в дочернем процессе ... $ pm-> finish; # Завершает дочерний процесс } [/ code] –

+0

О, я вижу! Это то же самое, но с расширенными функциями, такими как максимальное количество детей. Ухоженная. Спасибо, что указали! –