2010-07-13 4 views
0

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

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

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

Благодаря

Вот мой код:

eval { 

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

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

if([email protected]) { 

    if([email protected] eq "alarm\n") { print("Webpage Timed Out.\n\n"); }#if 
    else { die([email protected]"\n"); }#else 
}#if 
+0

Пожалуйста, вставьте/опишите вашу функцию синтаксического разбора/сканирования/выскабливания, спасибо. – miedwar

ответ

4

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

+0

Прости, что я должен был быть более ясным. Может быть, соскабливание было бы лучшим термином, а не ползанием. В основном я получаю применимое приложение из содержимого страницы, только входя в URL-адреса, которые приводят к более применимому контенту. Поэтому я не буду входить во многие URL-адреса, если таковые имеются, поэтому предел глубины всегда равен 1. Может ли это быть проблемой REGEX, где результаты бесконечны и продолжают запрашивать больше памяти? Мне это кажется маловероятным, но он бросает его туда. Есть ли способ выйти из функции в зависимости от того, сколько памяти используется программой? – user387049

+3

@ user387049 Да, это может быть полностью регулярное выражение. Безопасные сигналы означают, что сигнал тревоги не прерывает дискретную операцию Perl, такую ​​как регулярное выражение. См. Http://rt.perl.org/rt3//Public/Bug/Display.html?id=73464 – Schwern

+0

Использование Perl :: Unsafe :: Сигналы решили проблему.Некоторые REGEX блокировались, и сигнал тревоги не прерывался. Спасибо за помощь! – user387049

1

Вы можете остановиться на процессе сканирования.

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

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

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

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

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

+0

Я использую таймаут для UserAgent, но это относится только к получению страницы, а не после того, как я получу страницу. Я думаю, что проблема возникает после того, как я получу страницу. – user387049