SELECT(2)

名称
select - 同期的な入出力の多重化

ライブラリ
libc

書式
<sys/types.h> <sys/time.h> <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) FD_SET(fd, &fdset) FD_CLR(fd, &fdset) FD_ISSET(fd, &fdset) FD_ZERO(&fdset)

解説
select() は、 readfds, writefds および exceptfds でアドレスを渡された入出力記述子集合を調べ、 それらの記述子のいくつかがそれぞれ、読取り準備完了であるか、 書込み準備完了であるか、または保留されている例外条件があるかを調べます。 検出可能な唯一の例外条件は、ソケット上に受信した帯域外のデータです。 最初の nfds 個の記述子が各集合内でチェックされます。すなわち、記述子集合中の 0 〜 nfds-1 の記述子が調べられます。戻り時に select() は指定の記述子集合を、要求された操作の準備ができている記述子で 構成される部分集合で置き換えます。 select() は、すべての集合の中で準備ができた記述子の総数を返します。

記述子の集合は、整数配列内のビットフィールドとして保存されます。 このような記述子集合を操作するために次のマクロが用意されています。 FD_ZERO(&fdset) は記述子集合 fdset を空集合で初期化します。 FD_SET(fd, &fdset) は特定の記述子 fd を fdset に含めます。 FD_CLR(fd, &fdset) は fd を fdset から削除します。 FD_ISSET(fd, &fdset) は fd が fdset のメンバである場合は非 0 の値を、そうでない場合は 0 を返します。 これらのマクロの動作は、記述子の値が 0 未満であるか、または FD_SETSIZE 以上である場合は未定義です。 FD_SETSIZE は通常、少なくとも、システムがサポートする記述子の最大数に等しくなります。

timeout が、ヌルポインタでない場合、それはセレクションの完了を 待つ最大インターバルを指定します。 システムの活動性が、このインターバルを不定時間延長することがあります。

timeout がヌルポインタの場合、 select() は無期限にブロックします。

ポーリングのためには、 timeout 引数はヌルでなく、値が 0 の timeval 構造体を指しているべきです。

readfds, writefds および exceptfds のどれについても、いずれの記述子も興味がない場合は ヌルポインタを指定できます。

戻り値
select() は記述子集合に含まれている準備のできた記述子の数を返し、 エラーが起きた場合は -1 を返します。 タイムリミットが来ると、 select() は 0 を返します。 割り込みによるものも含めて select() がエラーで戻る場合は、記述子集合は変更されません。

エラー
select() から戻るエラーは次のことを示します。

[EBADF]
    記述子集合のどれかが無効な記述子を指定していました。

[EINTR]
    タイムリミットが切れる前あるいは選択したイベントのいずれかが起きる前に、 シグナルが配送されました。

[EINVAL]
    指定のタイムリミットは無効です。 どれかが負であるか、または大きすぎます。

[EINVAL]
    nfds が無効でした。

関連項目
accept(2), connect(2), getdtablesize(2), gettimeofday(2), read(2), recv(2), send(2), write(2), clocks(7)

注
FD_SETSIZE のデフォルトのサイズは現時点では 1024 です。 多数のオープンファイルを使用する可能性があるプログラムで select() を実行するために、 <sys/types.h> を取り込むヘッダを含める前にプログラムで FD_SETSIZE を定義することで、このサイズを増加できます。

nfds がオープンファイルの数より大きい場合、 select() が未使用のファイル記述子を調査することは保証されていません。 歴史的な理由で、 select() は最初の 256 個の記述子を必ず調査します。

バグ
susv2 では、システムが元の timeout を適当に更新することを許しています。 したがって、タイムアウトの値が select() 呼び出しによって変更されないと想定するのは賢明ではありません。

歴史
select() 関数は 4.2BSD で登場しました。