Linuxのファイルディスクリプタ、世論調査、選択

epollの機能の使用状況、および少しポーリングと選択

図1は、LTのファイルディスクリプタは、ポーリングと選択機能の改良版です。

機能は、コンテンツがある場合、バッファはそれらをすべて読み込まれるまで、バッファを読んだ後、バッファ、そして、イベントがepoll_wait関数が返すことです。

2、ETのファイルディスクリプタ(ブロッキング)

機能はバッファを読んだ後、バッファは内容にかかわらず存在し、イベントがepoll_wait機能が来てメッセージを送信し、再び最後まで戻らないということです。一部の読者が読むためにしばらく考えるだろうが、ファイル記述子がブロックされているので、致命的な問題があるので、ときプロセスはRECVをブロックに機能するすべて読み、その後、他に対処することはできないと推定接続されています。

図3に示すように、ファイルディスクリプタ(非ブロッキング)のET、最も効率的な方法。

機能はバッファを読んだ後、バッファは内容にかかわらず存在し、イベントがepoll_wait機能が来てメッセージを送信し、再び最後まで戻らないということです。しかし、あなたはfcntlのファイルディスクリプタを進めることができ、しばらくして読み込まれているように、非ブロック方式に設定され、それらすべてを読んだとき、recv関数はブロックされません。

ETは、ファイルディスクリプタ(非ブロッキング)例です。

#include <stdio.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, char** argv){

  int port = atoi(argv[1]);
  int lfd = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = INADDR_ANY;

  bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
  listen(lfd, 5);

  int efd = epoll_create(10);

  struct epoll_event re;
  re.events = EPOLLIN;
  re.data.fd = lfd;

  epoll_ctl(efd, EPOLL_CTL_ADD, lfd, &re);

  struct epoll_event events[100];
  
  while(1){
    int ret = epoll_wait(efd, events, 100, -1);
    printf("======================wait=======\n");
    if(ret == -1){
      perror("epoll_wait");
      exit(1);
    }

    for(int i = 0; i < ret; ++i){
      if(events[i].data.fd == lfd){
        int cfd = accept(lfd, NULL, NULL);

        int flags = fcntl(cfd, F_GETFL);
        flags |= O_NONBLOCK;
        fcntl(cfd, F_SETFL, flags);
    
        struct epoll_event re;
        re.events = EPOLLIN | EPOLLET;
        re.data.fd = cfd;
        epoll_ctl(efd, EPOLL_CTL_ADD, cfd, &re);
        break;
      }
      char buf[3];

      int ret;
      while((ret = recv(events[i].data.fd, buf, sizeof buf, 0)) > 0){
        write(STDOUT_FILENO, buf, ret);
      }
      
      if(ret == 0){
        epoll_ctl(efd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
        close(events[i].data.fd);
        printf("client disconnet\n");
      }
      else if(ret == -1 && errno == EAGAIN){
        printf("read over\n");  
      }
    }
  }
}

ポーリング関数の例:

#include <stdio.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char** argv){

  int port = atoi(argv[1]);
  int lfd = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = INADDR_ANY;

  bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
  listen(lfd, 5);

  struct pollfd pfd[1024];
  for(int i = 0; i < 1024; ++i){
    pfd[i].fd = -1;
  }
  pfd[0].fd = lfd;
  pfd[0].events = POLLIN;
  nfds_t maxfd = 0;
  
  while(1){
    int ret = poll(pfd, maxfd + 1, -1);
    printf("--------------poll------\n");
    if(pfd[0].revents & POLLIN){
      int cfd = accept(lfd, NULL, NULL);
      for(int i = 0; i < 1024; ++i){
        if(pfd[i].fd == -1){
          pfd[i].fd = cfd;
          pfd[i].events = POLLIN;
          maxfd++;
          break;
        }
      }
      continue;
    }

    for(int i = 0; i <= maxfd; ++i){
      if(pfd[i].revents & POLLIN){
        char buf[64];
        int ret = recv(pfd[i].fd, buf, sizeof buf, 0);
        if(ret == 0){
          pfd[i].fd = -1;
          close(pfd[i].fd);
          printf("client is disconnet\n");
        }
        else{
          write(STDOUT_FILENO, buf, ret);
        }
      }
    } 
    
  }
}

例としては、世論調査とのepollの比較で見ることができます。

  • epollは、事前に配列のサイズを決定する必要がありません。世論調査は必要です。
  • ファイルディスクリプタ内部効率が増加に接続されていない、赤黒木を用いて達成され、大幅に低くなります。ポーリングリストが実装されているので、パフォーマンスは、接続の増加に伴って減少します。世論調査では、Windowsで使用することはできません。epollは、クロスプラットフォームです。
  • 道の下では、カーネルコードで実装配列のサイズ選択の配列が死亡しているが書き込まれ、それが1024年ですが、私は唯一のカーネルを再コンパイル増加したいと思います。しかし、選択は、クロスプラットフォームです。

C / C ++相互学習のQQグループ:877 684 253

Iマイクロ手紙:xiaoshitou5854

おすすめ

転載: www.cnblogs.com/xiaoshiwang/p/11110204.html