LINUX下FD_SET紹介

3927 ワード

linuxの下でselectシステムの呼び出しを理解したばかりで、関数の原型は
1 #include <sys/select.h>

2 #include <sys/time.h>

3 int

4 select(int maxfdpl, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timeval *timeout);

readset,writeset,exceptsetの3つのパラメータの各パラメータに1つ以上の記述子を指定する方法は、設計上の問題です.selectは記述子セットを使用し、通常は整数配列であり、各整数の各ビットは記述子に対応する.例えば、32ビット整数が使用されると仮定すると、配列の第1の要素は記述子0〜31に対応し、第2の要素は32〜63に対応する.fd_という名前で隠すsetのデータ型と以下の4つのマクロ:
1 void FD_ZERO(fd_set *fdset);

2 void FD_SET(int fd, fd_set *fdset);

3 void FD_CLR(int fd, fd_set *fdset);

4 int FD_ISSET(int fd, fd_set *fdset); 

マクロFD_SET設定ファイル記述子セットfdsetにおけるファイル記述子fdに対応するビット(1に設定)、マクロFD_CLRクリアファイル記述子セットfdsetにおけるファイル記述子fdに対応するビット(0に設定)、マクロFD_ZEROは、ファイル記述子セットfdsetのすべてのビットをクリアする(すなわち、すべてのビットを0に設定する).この3つのマクロを使用して、selectを呼び出す前に記述子シールドビットを設定します.この3つのディスクリプタセットパラメータは値-結果パラメータであるため、selectを呼び出した後、結果はどのディスクリプタが準備されているかを示します.FD_の使用ISSETは、ファイル記述子セットfdsetにおけるファイル記述子fdに対応するビットが設定されているか否かを検出する.ディスクリプタセット内の未準備ディスクリプタに対応するビットの戻りはいずれも0になるため、select関数を再呼び出すたびに、すべてのディスクリプタセット内の関心のある位置を再び1にしなければならない.
通常、オペレーティングシステムはマクロFD_を介してSETSIZEは、1つのプロセスでselectが動作するファイル記述子の最大数を宣言する.多くのシステム実装は、4.4 BSDの:
1 #ifndef FD_SETSIZE

2 #define FD_SETSIZE 256

3 #endif

ただし、更新BSD由来のカーネルとSVR 4由来のカーネルはヘッダファイルで.
linuxでヘッダファイルでは、次のように記述されています.
1 /* Maximum number of file descriptors in `fd_set`. */

2 #define FD_SETSIZE        _FD_SETSIZE

_FD_SETSIZE定義/usr/include/linuxでのposix_types.h中:
1 /*

2  *This macro may hava been defined in <gnu/types.h>. But we    always use the one here.

3  */

4 #undef _FD_SETSIZE

5 #define _FD_SETSIZE        1024

FDをSETSIZEは、selectで使用されるディスクリプタセットのサイズを大きくするために、より大きな値として定義される.残念なことに、このようにするのは通常通用しません.selectはカーネルで実現され、カーネルのFD_をSETSIZEは上限使用と定義されている.したがって、FD_を大きくするSETSIZEはまたカーネルを再コンパイルします.注意すべきは、selectの代わりにpollを使用するアプリケーションがあり、記述子の限られた問題を避けることができることです.また、selectの典型的な実装では、記述子数が大きくなると拡張性の問題が発生する可能性がある.
一部のメーカーではselectの実装をプロセスを許可するように変更していますFD_SETSIZEは、BSD/OSなどのデフォルト値よりも大きい値として定義される.しかしながら、プログラムの移植性を考慮すると、このような使用は推奨されない.