7.22 ブロックせずに多くのファイルハンドルから読み取りを行う

などは入力を待ってブロックしてしまうが、ブロックさせるのではなく、入力が読み取り可能かどうか通知させるようにしたい。これは、パイプ、ソケット、デバイス、他のプログラムなどから読み取りを行う場合に役に立つ。

  • タイムアウト値を0秒にして、selectを呼び出す。
$rin = "";
# ポーリング対象の全てのファイルハンドルに対して、次の行を繰り返す。
vec($rin, fileno(FH1), 1) = 1;
vec($rin, fileno(FH2), 1) =1;
vec($fin, fileno(FH3), 1) = 1;

$nfound = select($rout=$rin, undef, undef, 0);
if ($nfound) {
  # 3つのファイルハンドルのうち、1つ以上が入力待ち
  if (vec($rout, fileno(FH1), 1)) {
    # FH1に対する処理を書く
  }
  if (vec($rout, fileno(FH2), 1)) {
    # FH2に対する処理を書く
  }
  if (vec($rout, fileno(FH3), 1)) {
    # FH3に対する処理を書く
  }
}
  • IO::Selectモジュールは、ビットベクタ演算を隠す抽象的なレイヤを提供する。
use IO::Select;

$select = IO::Select->new();
# ポーリング対象の全てのファイルハンドルに対して、次の行を繰り返す。
$select->add(*FILEHANDLE);
if (@ready = $select->can_read(0)) {
  # @ready内のファイルハンドルが入力待ち
}