Допустим, у меня есть тема:
sub new {
my $class = shift;
my $self = ref $class || $class;
bless { 'read_set' => IO::Select->new,
'write_set' => IO::Select->new,
'error_set' => IO::Select->new }, $self;
}
sub start {
my $self = shift;
$self->{'thread'} = threads->create(\&worker_thr, $self);
$self->{'thread'}->detach;
}
sub worker_thr {
my $self = shift;
while(1) {
my($read_active, $write_active, $error_active) =
IO::Select->select(
$self->{'read_set'},
$self->{'write_set'},
$self->{'error_set'},
undef
);
}
}
Поскольку я не предоставил время ожидания для select()
и оно блокируется на неопределенный срок до тех пор, пока не будет обнаружена активность на одном из наборов дескрипторов (ну, «дескриптор»), что произойдет, если другой поток изменяет содержимое наборов (например, добавляет новая розетка для опроса)?
Реализован ли он потокобезопасным способом по сравнению с реализацией потоков Perl POSIX?
Если нет, то я полагаю, что могу прикрепить блокирующий вызов select()
в блоке с его собственной областью действия и заблокировать наборы или, более аккуратно, все данные пакета. Как лучше всего разбудить select()
до возврата из другого потока, чтобы можно было манипулировать содержимым наборов? Специфичный для потока сигнал? Семафор? Предложения приветствуются.
Большое спасибо!
Редактировать: Что ж, специфичный для потока "сигнал" отсутствует. Как объясняется здесь (http://perldoc.perl.org/threads.html): «Соответственно, отправка сигнала в поток не нарушает операцию, над которой в данный момент работает поток: Сигнал будет действовать после завершения текущей операции. Например, если поток застревает в вызове ввода-вывода, отправка ему сигнала не приведет к прерыванию вызова ввода-вывода, так что сигнал немедленно активируется. "
Это все еще заставляет меня задуматься, как мне решить проблему пробуждения select()
в потоке, если я хочу, чтобы он блокировался бесконечно, а не возвращался после фиксированного времени ожидания.