\section{\module{select} ---
         I/O 処理の完了を待機する}

\declaremodule{builtin}{select}
\modulesynopsis{複数のストリームに対してI/O 処理の完了を待機します。}


このモジュールでは、ほとんどのオペレーティングシステムで利用可能な
\cfunction{select()} および \cfunction{poll()} 関数へのアクセス
機構を提供します。Windows の上ではソケットに対してしか動作しないので
注意してください; その他のオペレーティングシステムでは、他のファイル
形式でも (特に \UNIX ではパイプにも) 動作します。通常のファイルに
対して適用し、最後にファイルを読み出した時から内容が増えているかを
決定するために使うことはできません。

このモジュールでは以下の内容を定義しています:

\begin{excdesc}{error}
エラーが発生したときに送出される例外です。エラーに付属する
値は、 \cdata{errno} からとったエラーコードを表す数値とその
エラーコードに対応する文字列からなるペアで、\C{} 関数の
\cfunction{perror()} が出力するものと同様です。
\end{excdesc}

\begin{funcdesc}{poll}{}
(全てのオペレーティングシステムでサポートされているわけでは
ありません。) ポーリングオブジェクトを返します。このオブジェクトは
ファイル記述子を登録したり登録解除したりすることができ、
ファイル記述子に対する I/O イベント発生をポーリングすることが
できます; ポーリングオブジェクトが提供しているメソッドについては
下記の ~\ref{poll-objects} 節を参照してください。
\end{funcdesc}

\begin{funcdesc}{select}{iwtd, owtd, ewtd\optional{, timeout}}
\UNIX{} の \cfunction{select()} システムコールに対する直接的な
インタフェースです。最初の 3 つの引数は `待機可能なオブジェクト'
からなるシーケンスです: ファイル記述子を表す整数値、または
引数を持たず、整数を返すメソッド \method{fileno()} を持つ
オブジェクトです。待機可能なオブジェクトの 3 つのシーケンスはそれぞれ
入力、出力、そして `例外状態' に対応します。いずれかに空のシーケンスを
指定してもかまいませんが、3 つ全てを空のシーケンスにしてもよいかどうか
はプラットフォームに依存します (\UNIX{} では動作し、Windows では
動作しないことが知られています)。オプションの \var{timeout} 引数
にはタイムアウトまでの秒数を浮動小数点数型で指定します。
\var{timeout} 引数が省略された場合、関数は少なくとも一つのファイル
記述子が何らかの準備完了状態になるまでブロックします。
タイムアウト値ゼロは、ポーリングを行いブロックしないことを示します。

戻り値は準備完了状態のオブジェクトからなる 3 つのリストです:
従ってこのリストはそれぞれ関数の最初の 3 つの引数のサブセットに
なります。ファイル記述子のいずれも準備完了にならないままタイムアウト
した場合、3 つの空のリストが返されます。

シーケンスの中に含めることのできるオブジェクトは Python ファイル
オブジェクト (すなわち \code{sys.stdin}, あるいは \function{open()} や
\function{os.popen()} が返すオブジェクト)、\function{socket.socket()}
が返すソケットオブジェクト
\withsubitem{(in module socket)}{\ttindex{socket()}}
\withsubitem{(in module os)}{\ttindex{popen()}} です。
\dfn{wrapper} クラスを自分で定義することもできます。この場合、
適切な (単なる乱数ではなく本当のファイル記述子を返す)\method{fileno()} 
メソッドを持つ必要があります
\note{\function{select} はWindows のファイルオブジェクトを受理
しませんが、ソケットは受理します \index{WinSock} 。 Windows では、
背後の \cfunction{select()} 関数は WinSock ライブラリで提供されて
おり、WinSock によって生成されたものではないファイル記述子を扱う
ことができないのです}。
\end{funcdesc}

\subsection{ポーリングオブジェクト
            \label{poll-objects}}

\cfunction{poll()} システムコールはほとんどの \UNIX{} システムでサポート
されており、非常に多数のクライアントに同時にサービスを提供するような
ネットワークサーバが高い拡張性を持てるようにしています。
\cfunction{poll()} に高い拡張性があるのは、\cfunction{select()} が
ビット対応表を構築し、対象ファイルの記述子に対応するビットを立て、
その後全ての対応表の全てのビットを線形探索するのに対し、
\cfunction{poll()} は対象のファイル記述子を列挙するだけでよいから
です。
\cfunction{select()} は O(最大のファイル記述子番号) なのに対し、
\cfunction{poll()} は O(対象とするファイル記述子の数) で済みます。

\begin{methoddesc}[poll]{register}{fd\optional{, eventmask}}
ファイル記述子をポーリングオブジェクトに登録します。これ以降の
\method{poll()} メソッド呼び出しでは、そのファイル記述子に処理待ち中の
I/O イベントがあるかどうかを監視します。\var{fd} は整数か、
整数値を返す \method{fileno()} メソッドを持つオブジェクトを取ります。
ファイルオブジェクトも通常 \method{fileno()} を実装しているので、
引数として使うことができます。

\var{eventmask} はオプションのビットマスクで、どのタイプの I/O イベント
を監視したいかを記述します。この値は以下の表で述べる定数 \constant{POLLIN}、
\constant{POLLPRI}、および \constant{POLLOUT} の組み合わせにすることが
できます。ビットマスクを指定しない場合、標準の値が使われ、
3 種のイベント全てに対して監視が行われます。

\begin{tableii}{l|l}{constant}{定数}{意味}
  \lineii{POLLIN}{読み出せるデータの存在}
  \lineii{POLLPRI}{緊急の読み出しデータの存在}
  \lineii{POLLOUT}{書き出せるかどうか: 書き出し処理がブロックしないかどうか}
  \lineii{POLLERR}{何らかのエラー状態}
  \lineii{POLLHUP}{ハングアップ}
  \lineii{POLLNVAL}{無効な要求: 記述子が開かれていない}
\end{tableii}

すでに登録済みのファイル記述子を登録してもエラーにはならず、
一度だけ登録した場合と同じ効果になります。
\end{methoddesc}

\begin{methoddesc}[poll]{unregister}{fd}
ポーリングオブジェクトによって追跡中のファイル記述子を登録解除します。
\method{register()} メソッドと同様に、\var{fd} は整数か、
整数値を返す \method{fileno()} メソッドを持つオブジェクトを取ります。

登録されていないファイル記述子を登録解除しようとすると
\exception{KeyError} 例外が送出されます。
\end{methoddesc}

\begin{methoddesc}[poll]{poll}{\optional{timeout}}
登録されたファイル記述子に対してポーリングを行い、
報告すべき I/O イベントまたはエラーの発生したファイル記述子に
毎に 2 要素のタプル \code{(\var{fd}, \var{event})} からなるリスト
を返します。リストは空になることもあります。
\var{fd} はファイル記述子で、\var{event} は該当するファイル記述子
について報告されたイベントを表すビットマスクです --- 例えば
\constant{POLLIN} は入力待ちを示し、\constant{POLLOUT} はファイル記述子
に対する書き込みが可能を示す、などです。
空のリストは呼び出しがタイムアウトしたか、報告すべきイベントが
どのファイル記述子でも発生しなかったことを示します。
\var{timeout} が与えられた場合、処理を戻すまで待機する時間の長さを
ミリ秒単位で指定します。\var{timeout} が省略されたり、負の値であったり、
あるいは \constant{None} の場合、そのポーリングオブジェクトが監視している
何らかのイベントが発生するまでブロックします。
\end{methoddesc}


