URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 6819
[ Назад ]

Исходное сообщение
"Модулb threads, Sys::SigAction и команда alarm."

Отправлено jr , 08-Окт-07 15:28 
Не могу победить реализацию таймаута в треде.

Вот код, который работает:
-------------------------------------------------------------------------
#!/usr/bin/perl -w
use strict;
use threads;
use Sys::SigAction qw( set_sig_handler );
t();
sub t {
   eval {
      set_sig_handler( 'ALRM', sub { die 'alarm!' } );
      alarm(1); # определяем таймаут в 1 сек.
      sleep(10); # здесь вместо sleep должен быть полезный код
      alarm(0);
   };
   alarm(0);
   if( $@ ) {
      print "Timeout!\n";
   }
   else {
      print "Ok\n";
   }
}
-------------------------------------------------------------------------
Т.е. реализация таймаута нормально отрабатывает

А вот код, который не работает (меняем только одну строчку вызова функции t):
-------------------------------------------------------------------------
#!/usr/bin/perl -w
use strict;
use threads;
use Sys::SigAction qw( set_sig_handler );
threads->new( \&t )->join(); # вместо простого вызова функции t
sub t {
   eval {
      set_sig_handler( 'ALRM', sub { die 'alarm!' } );
      alarm(1); # определяем таймаут в 1 сек.
      sleep(10); # здесь вместо sleep должен быть полезный код
      alarm(0);
   };
   alarm(0);
   if( $@ ) {
      print "Timeout!\n";
   }
   else {
      print "Ok\n";
   }
}
-------------------------------------------------------------------------
Тут через секунду программа вылетает с ошибкой:
Signal SIGALRM received, but no signal handler set.

Как побороть все это - не знаю...


Содержание

Сообщения в этом обсуждении
"Модулb threads, Sys::SigAction и команда alarm."
Отправлено angra , 08-Окт-07 15:53 
man perlthtut

Similarly, mixing signals and threads should not be attempted.  Implementations are platform-dependent, and even the POSIX semantics may not be what you expect (and Perl doesn't even give you the full POSIX API).

для тредов есть другие методики, позволяющие реализовать подобное.


"Модулb threads, Sys::SigAction и команда alarm."
Отправлено jr , 08-Окт-07 15:58 
>man perlthtut
>
>Similarly, mixing signals and threads should not be attempted.  Implementations are
>platform-dependent, and even the POSIX semantics may not be what you
>expect (and Perl doesn't even give you the full POSIX API).
>
>
>для тредов есть другие методики, позволяющие реализовать подобное.

Хм... а где о них, о методиках этих почитать можно?


"Модулb threads, Sys::SigAction и команда alarm."
Отправлено alexvs , 07-Ноя-07 14:47 
>man perlthtut
>
>Similarly, mixing signals and threads should not be attempted.  Implementations are
>platform-dependent, and even the POSIX semantics may not be what you
>expect (and Perl doesn't even give you the full POSIX API).
>
>
>для тредов есть другие методики, позволяющие реализовать подобное.

Ответ просто "радует" своей полнотой и просветляющей способностью :(

Есть тред в котором открываю пайп и читаю из него. Как убить тред через N секунд?
my $first = threads->create(\&Tail);
sleep(10);
my $some = $first->kill('KILL')->join();

sub Tail {
   $SIG{'KILL'} = sub { close(TFH); threads->exit(); };
   open(TFN,'tail -F -n 0 some_file |');
   while(<TFN>) {
      ...
   }
   return $some;
}

работает, до тех пор пока в файл что-то пишется. Если файл не изменяется, то всё залипает на 'while(<TFN>)'.


"Модулb threads, Sys::SigAction и команда alarm."
Отправлено jr , 07-Ноя-07 14:54 
>[оверквотинг удален]
>sub Tail {
>   $SIG{'KILL'} = sub { close(TFH); threads->exit(); };
>   open(TFN,'tail -F -n 0 some_file |');
>   while(<TFN>) {
>      ...
>   }
>   return $some;
>}
>
>работает, до тех пор пока в файл что-то пишется. Если файл не изменяется, то всё залипает на 'while(<TFN>)'.

Насколько я понял изучая вопрос, треды и сигналы (в понимании, в котором сигналы и должны быть) в perl не работают...
Мне пришлось все на fork переделывать, т.к. без ALRM я не смог обойтись.