Виснет на $sock->recv. Perl под Windows.

Тема в разделе "Perl программирование", создана пользователем DenisPerm, 27 июн 2008.

  1. DenisPerm

    DenisPerm New Member

    Регистрация:
    27 июн 2008
    Сообщения:
    2
    Симпатии:
    0
    Не работает вот такая конструкция:

    eval{
    local $SIG{ALRM} = sub { die "Net::NTP timed out geting NTP packet\n"; };
    alarm($TIMEOUT);
    $sock->recv($data,960) or die "recv() failed: $!\n";
    alarm(0)
    };

    Если идет обращение к несуществующему хосту, то виснет на $sock->recv.
    Если ответ от хоста есть, то все нормально.

    В чем дело и как правильно это реализуется ?
     
  2. Vovochka

    Vovochka Гость

  3. DenisPerm

    DenisPerm New Member

    Регистрация:
    27 июн 2008
    Сообщения:
    2
    Симпатии:
    0
    Нее. Винда точно XP.
    Да и сама конструкция alarm работает.
    Т. е. если $sock->recv заменить на sleep,
    то alarm через TIMEOUT работает.

    Виснет именно $sock->recv.

    И я ХЗ что с этим делать.
    Самый смех, что текст их модуля Net-NTP.
    И модулю то 300 лет.
     
  4. Vovochka

    Vovochka Гость

    Хех :)
    Может вместо эвала попробовать в поток обернуть?
    Хотя вряд ли оно того стоит.
     
  5. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Слабо представляю что делает ваш код на Перле, но все же...
    В MSDN (Winsocks v.2) по поводу recv сказано:
    Т.е. будет висеть пока не пойдут данные.
     
  6. Vovochka

    Vovochka Гость

    В том то и прикол. Этот хак (код) помогает избавиться от блокировки:
    Код (Text):
    local $SIG{ALRM} = sub { die "Net::NTP timed out geting NTP packet\n"; };
    Присваиваем обработчик для сигнала SIGALART
    С этим обработчиком при получении сигнала программа должна "умереть", но так как этот участок кода завернут в eval, то просто мы выпадем из этого блока.
    Код (Text):
    alarm($TIMEOUT);
    Заказываем SIGALARM через $TIMEOUT сек.
    Код (Text):
    $sock->recv($data,960) or die "recv() failed: $!\n";
    Блокирующий вызов.
    Код (Text):
    alarm(0);
    Мы не выпали из блока, значит блокирующий вызов завершился. Отказываемся от заказа на SIGALARM
    Вот такая вот ботва :)
     
  7. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Спасибо, что пояснили...Я же говорил, что:
     
Загрузка...

Поделиться этой страницей