epollの man ページには、次のようなエッジ トリガーのサンプル コードがあります。
for (;;) {
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if (nfds == -1) {
perror("epoll_pwait");
exit(EXIT_FAILURE);
}
for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == listen_sock) {
conn_sock = accept(listen_sock,
(struct sockaddr *) &local, &addrlen);
if (conn_sock == -1) {
perror("accept");
exit(EXIT_FAILURE);
}
setnonblocking(conn_sock);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
&ev) == -1) {
perror("epoll_ctl: conn_sock");
exit(EXIT_FAILURE);
}
} else {
do_use_fd(events[n].data.fd);
}
}
}
関数 do_use_fd では、ブロックされていない recv を while ループで EAGAIN まで呼び出すと、サンプル コードは正常に動作します。
このサンプル コードについて質問があります。50 個のソケット クライアント接続があり、突然 10 個のクライアントが同時にデータを書き込むとします。そのため、epoll_wait() は 10 を返し、次に for ループに進みます。
for (n = 0; n < nfds; ++n)
これらの 10 個のクライアントを呼び出し do_use_fd(events[n].data.fd);
ます。n=5 が完了し、n=6 がまだ完了していないとします。10 個のイベントがすべて完了し、epoll_wait に戻った後、突然、イベント n=3 のファイル記述が新しいデータを受け取りました。 、クライアントが読み取る新しいデータがあることを通知するイベントを取得できますか? または、イベントが発生したときにコードが epoll_wait にないため、見逃してしまいます!!