линукс Epoll, опрос, выберите

Использование Epoll функции, и немного опроса и выберите

1, LT Epoll является улучшенной версией опроса и выбора функций.

Особенностью является то, что после прочтения буфера, буфер, если есть содержание, то, epoll_wait функция будет возвращать до тех пор, пока буфер не будет читать их все.

2, Epoll ET (в блокирование)

Особенностью является то, что после прочтения буфера, буфер существует независимо от содержания, epoll_wait функция не вернется до конца еще раз отправить сообщение, чтобы прибыть. Подсчитано, что некоторые читатели будут думать некоторое время, чтобы читать, но есть фатальная проблема, потому что дескрипторы файлов блокируются, поэтому, когда все показания, где процесс будет функционировать в блокировании ПРИЕМА, а затем не в состоянии иметь дело с другими подключен.

3, ЭТ в Epoll (без блокировки), наиболее эффективным способом.

Особенностью является то, что после прочтения буфера, буфер существует независимо от содержания, epoll_wait функция не вернется до конца еще раз отправить сообщение, чтобы прибыть. Но вы можете перейти с дескриптором Fcntl файла устанавливаются в неблокируемом образом, так что через некоторое время было прочитано, когда прочитал их все, функция RECV не будет заблокирована.

ЕТ является Epoll (без блокировки) Примеры:

#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 не нужно заранее решить, размер массива. опрос потребностей.
  • Epoll внутренняя эффективность достигается с помощью красно-черного дерева, не связанного с увеличением, значительно становится низкой. список Опрос реализован, поэтому производительность уменьшается с увеличением связи. Опрос не может быть использован в окнах. Epoll является кросс-платформенным.
  • В пути, размер массива является массивом выбора умер реализован код ядра написано, то есть 1024, я хотел бы увеличить только перекомпилировать ядро. Но выбор является кросс-платформенным.

C / C ++ взаимное обучение QQ группы: 877 684 253

Я микро письмо: xiaoshitou5854

рекомендация

отwww.cnblogs.com/xiaoshiwang/p/11110204.html