2

私がスレッドを持っているとしましょう:

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()、記述子(「ハンドル」)セットの1つでアクティビティが検出されるまで無期限にブロックされるため、別のスレッドがセットの内容を変更した場合(たとえば、ポーリング用の新しいソケットを追加した場合)はどうなりますか?

Perl POSIXスレッドの実装と比較して、スレッドセーフな方法で実装されていますか?

そうでない場合は、ブロッキングselect()呼び出しを独自のスコープを持つブロックに固定して、セット、またはよりクリーンなパッケージデータ全体をロックできると思います。select()セットの内容を操作できるように、別のスレッドからウェイクアップして戻るための最良の方法は何ですか?スレッド固有のシグナル?セマフォ?提案を歓迎します。

どうもありがとう!

編集:まあ、スレッド固有の「シグナル」が出ています。ここで説明されているように(http://perldoc.perl.org/threads.html):「それに応じて、スレッドにシグナルを送信しても、スレッドが現在作業している操作は中断されません。シグナルは、現在の操作の後に処理されます。たとえば、スレッドがI / O呼び出しでスタックしている場合、信号を送信してもI / O呼び出しが中断されることはなく、信号はすぐに実行されます。」

それでもselect()、一定のタイムアウト後に戻るのではなく、スレッドを無期限にブロックしたい場合、スレッドでウェイクアップする問題をどのように処理すればよいのか疑問に思います。

4

1 に答える 1

2

デフォルトでは、perl スレッドはデータを共有しないため、1 つのスレッドがそのセットを変更しても、他のスレッドには影響しません。そうです、それはスレッドセーフですが、おそらくあなたがやりたいことをしません。

選択をブロックしている別のスレッドまたはプロセスを本当にウェイクアップしたい場合、簡単な解決策はパイプを読み取りキューに追加することです。その後、そのパイプにバイトを書き込むことでウェイクアップできます。

于 2009-06-18T09:49:06.003 に答える