3

イベントが結合されているかどうかについてのドキュメントは不明であり、私のテストでは、それらが常にではなく、場合によっては結合されていることが示されています。

考慮してくださいman 7 epoll

エッジ トリガーのepollでも、データの複数のチャンクを受信すると複数のイベントが生成される可能性があるため 、呼び出し元には EPOLLONESHOT フラグを指定するオプションがあります...

および Q&A セクション:

Q7 epoll_wait(2) 呼び出しの間に複数のイベントが発生した場合、それらは結合されますか、それとも別々に報告されますか?

A7 統合されます。

マニュアルの最初のステートメントは、ソケットからの読み取り、パケットの到着、それの読み取り、別のパケットの到着などの状況で複数の EPOLLIN イベントを受信できることを意味していると思います。また、Q&A セクションの回答は、EPOLLIN や EPOLLOUT などのさまざまなイベントに関するものです。私が間違っている場合は、私を修正してください。

epoll がどのように機能するかをよりよく理解するためにいくつかのコードをいじっていましたが、別のイベントが設定されているかどうかに基づいて、同じ種類のイベントに関して異なる動作をしているように見えます。より正確には、EPOLLIN のみを待機している場合、複数の入力が 1 つのイベントを生成しますが、EPOLLIN と EPOLLOUT の両方を待機している場合、複数の入力が複数のイベントを生成します。

これをテストするために使用したコードは次のとおりです。

#include <stdio.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
  struct epoll_event ev = {EPOLLIN|EPOLLOUT|EPOLLET};
  int epoll = epoll_create1(0);
  epoll_ctl(epoll, EPOLL_CTL_ADD, 0, &ev);

  //async stdin
  int flags = fcntl(0, F_GETFL);
  flags |= O_NONBLOCK;
  fcntl(0, F_SETFL, flags);

  while(1){
    struct epoll_event events[64];
    int n = epoll_wait(epoll, events, 64, -1);

    printf("Event count: %d\n", n);

    if(events[0].events == EPOLLIN)
      printf("EPOLLIN only\n\n");

    else
    if(events[0].events == (EPOLLIN|EPOLLOUT))
      printf("EPOLLIN and EPOLLOUT\n\n");

    else
      printf("EPOLLOUT only\n\n");

    char buffer[256];
    read(0, buffer, 256);

    sleep(1);
  }
  return 0;
}

Return キーを押した後の出力は、EPOLLIN と EPOLLOUT の両方が受信されたことを示しています。このメッセージは、Return キーが押された回数だけ表示され、EPOLLOUT のみが生成されていることを示しています。

しかし、EPOLLOUT フラグを指定せずにプログラムをコンパイルし、Return キーを何度も押すと、1 つのイベントが 1 回だけ報告されます。

呼び出しを削除するreadと、EPOLLOUT が設定されている場合は EPOLLIN が引き続き報告されますが、EPOLLIN のみが設定されている場合は報告されません。

待機しているイベントに依存する動作ですか、それともテスト コードに何か問題がありますか? 依存している場合は、今後も変わらないので安心できますか?

4

1 に答える 1