epoll
fs/eventpoll.cに由来する “event poll” → epoll
ファイルディスクリプタを見に行くときの計算量が$ O(1) なのでパフォーマンスが良い
ファイルディスクリプタの監視をカーネル空間で行っているため
epollのサンプル実装はGeekなページのやつが参考になる
sys/epoll.hを使う
使用できる関数
table:sys/epoll.h
関数 Kernel
epoll_create(2) 2.6
epoll_create1(2) 2.6.27
epoll_ctl(2) 2.6
epoll_pwait(2) 2.6.19
epoll_pwait2(2) 5.11
epoll_wait(2) 2.6
code:memo.c
int epoll_create(int size);
int epoll_create1(int flags);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,
int maxevents, int timeout,
const sigset_t *_Nullable sigmask);
int epoll_pwait2(int epfd, struct epoll_event *events,
int maxevents, const struct timespec *_Nullable timeout,
const sigset_t *_Nullable sigmask);
関連するカーネルパラメータ
/proc/sys/fs/epoll/max_user_watches
code:memo.c
// 非ブロッキング + EAGAIN まで読み切りの実装
static void do_use_fd(int fd) {
for (;;) {
ssize_t n = read(fd, buf, sizeof buf);
if (n > 0) {
// 受け取ったデータを処理(キューに積む等)
continue; // まだ読めるかもしれないのでループ継続
}
if (n == 0) {
// EOF(対向がclose)
close(fd);
break;
}
if (n < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
// ここまでで読み尽くした → 次のエッジを待つ
break;
}
if (errno == EINTR) {
continue; // 割り込み → 再試行
}
// その他のエラー
perror("read");
close(fd);
break;
}
}
}
関連API
関連
確認用
Q. epoll
参考
メモ
read, writeはストリームに書くシステムコール
TCPでストリームを作り接続するためのシステムコールがscoket(2), connect(2), bind(2), listen(2), accept(2)