私はepollの使い方を学んでいて、次の例を書きました
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <unistd.h>
int main() {
int epfd;
struct epoll_event ev;
struct epoll_event ret;
char buf[200];
int n,k,t;
epfd = epoll_create(100);
assert(0 ==
fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK)
);
ev.data.fd = 0;
ev.events = EPOLLIN | EPOLLET;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev) != 0)
perror("epoll_ctl");
while((n = epoll_wait(epfd, &ret, 1, -1)) > 0) {
printf("tick!\n");
if(ret.data.fd == 0) {
k=0;
while((t=read(0, buf, 100)) > 0) {
k+=t;
}
if(k == 0) {
close(0);
printf("stdin done\n");
}
}
}
perror("epoll");
return 0;
}
ターミナルで実行しようとすると、fds 0、1、および 2 がすべて同じ開いているファイルを指しているため、適切に動作しません。そのため、close(0) は epoll セットから stdin を削除しません。「cat | ./a.out」を実行することで、これを回避できます。汚いトリックですが、名前付きパイプまたはソケットを使用して小さな例を設定すると、より複雑になります。
これで、すべてが機能し、ファイルは epoll セットから削除されますが、空のセット上にあるため、次の epoll_wait 呼び出しは永久にブロックされます! したがって、epoll ファイル記述子 (epfd) が空の epoll セットであるかどうかを検出する必要があります。
どうすればこれを回避できますか? (一般的な方法で、stdin が完了したときに exit を呼び出すだけではありません) ありがとう!