0

epoll のドキュメントからこれを理解するのに苦労してpipe(fd)fd[0]ますfd[1]。に何かを書き込んfd[1]で閉じます。

write(fd[1], "abc", 3);
write(fd[1], "def", 3);
close(fd[1]);

潜在的に同時に、epoll インスタンスを作成し、それが から読み取れるようになるまで待機するように指示し、読み取り可能になっfd[0]たら 3 バイトを読み取ります。

int epoll_fd = epoll_create(10);
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = fd[0];
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd[0], &ev);

struct epoll_event event;
epoll_wait(epoll_fd, &event, 1, -1);
char buffer[100];
read(fd[0], buffer, 3);

ここで、epoll_waitもう一度呼び出します。パイプが閉じられていても、カーネルにはまだ 3 バイトがバッファリングされているはずfd[0]です。したがって、次が機能することを期待しています(つまり、ブロックしません):

epoll_wait(epoll_fd, &event, 1, -1);
read(fd[0], buffer, 3);  // buffer should start with "def" now

これで、パイプには何も残っておらず、書き込み側が閉じられています。epoll_wait3 度目の場合はどうすればよいですか?

epoll_wait(epoll_fd, &event, 1, -1);  // will this block indefinitely?
read(fd[0], buffer, 3);

ここで異なる答えを示しているように見える 2 つの異なるコードがあります。

4

2 に答える 2

3

閉じているパイプの書き込み終了は、0 を返す read() で通知する必要があります。

仮定:

  • epoll エッジ トリガーを使用していない
  • すべての呼び出しでエラーをチェックしました。
  • 書き込み終了は実際にクローズされています (つまり、dup() 呼び出しや fork() などから漏れた記述子はありません)。

その場合、最後の epoll_wait はブロックされず、次の read() は 0 を返す必要があります。

(そして、 read() が返すと想定するバイト数を返すことを忘れずに確認してください)

于 2013-11-09T02:26:52.793 に答える
0

あなたの投稿のこの行について:

epoll_wait(epoll_fd, &event, 1, -1);  // will this block indefinitely?  

maxevents引数は に設定されている1ため、関係なく最大 1 つのイベントしか表示されませんが、それはあなたの質問とはほとんど関係ありません。タイムアウト引数が に設定されている
場合、これにより無期限にブロックされます-1epoll_wait()

ブロックしたくない場合、または一定の時間を渡したくない場合は、タイムアウトに0を渡すと、epoll_wait() イベントがなくてもすぐに戻ります。

于 2013-11-09T02:25:37.167 に答える