2009-06-18 10 views
2

のは、私がスレッドを持っているとしましょう:活動は、記述子のいずれかで検出されるまで無期限にブロック私はselect()にタイムアウトを提供していないのでselect()ラッパーはIO :: Selectスレッドセーフであるか?どのように回避するには?

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 
        ); 
     } 

}  

、それが(まあ、「ハンドル」)、別の場合には何が起こるか、設定しますスレッドはセットの内容を変更します(ポーリングのための新しいソケットを追加するなど)?

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

もしそうでなければ、ブロックselect()を独自の有効範囲を持つブロックでスティックして、セットをロックするか、より完全にパッケージデータをロックすることができます。復帰する最善の方法は何ですか?select()他のスレッドからセットの内容を操作できるようにしますか?スレッド固有のシグナル?セマフォ?提案は大歓迎です。

ありがとうございました!

編集:スレッド固有の「信号」が出力されています。ここで説明したように(http://perldoc.perl.org/threads.html)、「対応して、信号をスレッドに送信しても、そのスレッドが現在処理中の操作は中断されません:現在の操作が完了した後に信号が処理されます。 I/Oコール、信号を送信しても、I/Oコールが中断されて信号がすぐに作動することはありません。

それでも、固定タイムアウト後に無期限にブロックするのであれば、スレッドでselect()を呼び起こす問題をどのように処理すればいいのか不思議です。

答えて

2

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

実際にselectでブロックされている別のスレッドまたはプロセスをウェイクアップさせたい場合は、そのキューにパイプを追加するのが簡単です。そのパイプにバイトを書き込んで目を覚ますことができます。

+0

ねえ、それは悪い考えではありません! –

関連する問題