Perl будильник работает с перебоями - PullRequest
0 голосов
/ 13 июля 2010

В настоящее время я работаю над проектом, который включает сканирование определенных веб-сайтов. Однако иногда моя Perl-программа по какой-то причине «застревает» на веб-сайте (не может понять, почему), и программа зависает на несколько часов. Чтобы обойти это, я вставил некоторый код для тайм-аута в подпрограмму, которая сканирует веб-страницу. Проблема заключается в том, что, допустим, я установил будильник на 60 секунд, большую часть времени страница корректно отключается, но иногда программа не срабатывает и просто просидела несколько часов подряд (возможно, навсегда, так как я обычно убиваю программа).

На действительно плохих веб-сайтах программа Perl просто забирает мою память, занимая 2,3 ГБ ОЗУ и 13 ГБ подкачки. Также использование процессора будет высоким, и мой компьютер будет вялым. К счастью, если время ожидания истекло, все ресурсы быстро освобождаются.

Это мой код или проблема с Perl? Что я должен исправить и почему это вызвало эту проблему?

Спасибо

Вот мой код:

eval {

    local $SIG{ALRM} = sub { die("alarm\n") };

    alarm 60;
    &parsePageFunction();
    alarm 0;
};#eval

if($@) {

    if($@ eq "alarm\n") { print("Webpage Timed Out.\n\n"); }#if
    else { die($@."\n"); }#else
}#if

Ответы [ 2 ]

4 голосов
/ 13 июля 2010

В зависимости от того, где именно в коде он застревает, вы можете столкнуться с проблемой с безопасными сигналами perl . См. Документацию по обходным путям в perlipc (например, Perl :: Unsafe :: Signals ).

1 голос
/ 13 июля 2010

Возможно, вы захотите уточнить процесс сканирования.

Я предполагаю, что это рекурсивное сканирование, при котором для каждой просканированной страницы вы сканируете все ссылки на ней и повторяете также сканирование всех ссылок на всех этих страницах.

Если это так, вы можете сделать две вещи:

  1. Создайте какой-то предел глубины, при каждой рекурсии вы увеличиваете счетчик и прекращаете сканирование, если предел достигнут

  2. Обнаружение циклической ссылки, если у вас есть PAGE_A со ссылкой на PAGE_B, а у PAGE_B есть ссылка на PAGE_A, которую вы будете сканировать, пока не закончится память.

Кроме этого, вы должны изучить использование стандартного тайм-аута модуля, который вы используете, если это LWP::UserAgent вы делаете LWP::UserAgent->new(timeout => 60)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...