int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
nfds は 3 つの集合に含まれるファイルディスクリプタの最大値に 1 を足したものである。 ファイルディスクリプタの最大値がsとわかっていればnfds=s+1となります。
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
select()を使うための基本的な流れ
FD_ZERO() -> FD_SET() -> tvの設定 -> select() -> select()戻り値の監視 -> FD_ISSET()
FD_ZERO(): select()で監視するファイルディスクリプタを設定する構造体(readfds, writefds, exceptfds)を初期化します。
FD_SET(): 監視したいファイルディスクリプタをxxxfdsに設定します。
tvの設定: select()を監視するタイミングを設定する構造体
select(): xxxfdsを監視します。
FD_ISSET(): ファイルディスクリプタに変化があったかどうかを調べます。
int main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
/* stdin (fd 0) を監視し、入力があった場合に表示する。*/
FD_ZERO(&rfds);
// select()にはfd_setとしてreadfds, writefds, exceptfdsを設定することができます。
// select()で監視をしたいfd_setについてはFD_ZERO()で初期化をします。
FD_SET(0, &rfds);
/* 5 秒間監視する。*/
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* この時点での tv の値を信頼してはならない。*/
// tvの値は再度設定する必要があります。
// もしくはselect()が戻ってきた時間をはかるための指標にはなりません。
if (retval == -1)
perror("select()");
else if (retval)
printf("今、データが取得できました。\n");
/* FD_ISSET(0, &rfds) が true になる。*/
else
printf("5 秒以内にデータが入力されませんでした。\n");
exit(EXIT_SUCCESS);
}