select()の使い方

Last-modified: 2008-04-23 (水) 22:32:57

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);
}
 

Manpage of SELECT