select
システムコールのselectについて
ファイルディスクリプタを監視して同期I/Oの多重化ができる
古いAPIで、1024個しかディスクリプタを監視できない
pollやepollを使った方がよい
3つのファイルディスクリプタの集合を監視する
読み込み可能かを監視するファイルディスクリプタ集合
書き込み
code:memo.c
#include <sys/select.h>
// struct timeval timeout 秒・マイクロ秒単位
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
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);
#define _XOPEN_SOURCE 600
#include <sys/select.h>
// struct timespec timeout 秒・ナノ秒単位
int pselect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask);
nfds
何個のファイルディスクリプタを監視するか
readfds
読み込みが可能かどうかを監視する用
writefds
停止せずに書き込みが可能かどうかを監視する用
exceptfds
例外の監視
timeout
タイムアウトまでの時間
返り値
readdfs、writedfs、exceptfdsでready状態になったものの総数
code:select.c
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void) {
/* stdin (fd 0) を監視し、入力があった場合に表示する。*/
fd_set rfds;
// ファイルディスクリプタの集合を消去する
FD_ZERO(&rfds);
// ファイルディスクリプタの集合への追加
FD_SET(0, &rfds);
/* 最大5秒間監視する。*/
struct timeval tv;
tv.tv_sec = 5;
tv.tv_usec = 0;
/* ここでは1個のファイルディスクリプタ(stdin(0))が読み込み可能かを最大5秒待つ */
int retval = select(1, &rfds, NULL, NULL, &tv);
// エラーが起こった場合、この時点でのtvの中身は未定義となるため
// tv の値を信頼してはならない
if (retval == -1) {
perror("select()");
} else if (retval) {
printf("今、データが取得できました。\n");
/* FD_ISSET(0, &rfds) が true になる。*/
} else {
printf("5 秒以内にデータが入力されませんでした。\n");
}
return 0;
}
確認用
Q. select
Q. pselect
参考
select - システムコールの説明 - Linux コマンド集 一覧表
select() - IBM Documentation
関連
排他制御
シグナル
sigprocmask()
I/Oの多重化
#ソケット通信