Не могу победить реализацию таймаута в треде.Вот код, который работает:
-------------------------------------------------------------------------
#!/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.Как побороть все это - не знаю...
man perlthtutSimilarly, 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).
для тредов есть другие методики, позволяющие реализовать подобное.
>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).
>
>
>для тредов есть другие методики, позволяющие реализовать подобное.Хм... а где о них, о методиках этих почитать можно?
>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>)'.
>[оверквотинг удален]
>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 я не смог обойтись.