2.4 epoll API

2.4.1 创建EPOLL

  1. /**
  2. * @param size 告诉内核监听的数目
  3. *
  4. * @returns 返回一个epoll句柄(即一个文件描述符)
  5. */
  6. int epoll_create(int size);
  1. int epfd = epoll_create(1000);

2.4 epoll API - 图1

2.4.2 控制EPOLL

  1. /**
  2. * @param epfd 用epoll_create所创建的epoll句柄
  3. * @param op 表示对epoll监控描述符控制的动作
  4. *
  5. * EPOLL_CTL_ADD(注册新的fd到epfd)
  6. * EPOLL_CTL_MOD(修改已经注册的fd的监听事件)
  7. * EPOLL_CTL_DEL(epfd删除一个fd)
  8. *
  9. * @param fd 需要监听的文件描述符
  10. * @param event 告诉内核需要监听的事件
  11. *
  12. * @returns 成功返回0,失败返回-1, errno查看错误信息
  13. */
  14. int epoll_ctl(int epfd, int op, int fd,
  15. struct epoll_event *event);
  16. struct epoll_event {
  17. __uint32_t events; /* epoll 事件 */
  18. epoll_data_t data; /* 用户传递的数据 */
  19. }
  20. /*
  21. * events : {EPOLLIN, EPOLLOUT, EPOLLPRI,
  22. EPOLLHUP, EPOLLET, EPOLLONESHOT}
  23. */
  24. typedef union epoll_data {
  25. void *ptr;
  26. int fd;
  27. uint32_t u32;
  28. uint64_t u64;
  29. } epoll_data_t;
  1. struct epoll_event new_event;
  2. new_event.events = EPOLLIN | EPOLLOUT;
  3. new_event.data.fd = 5;
  4. epoll_ctl(epfd, EPOLL_CTL_ADD, 5, &new_event);

2.4 epoll API - 图2

2.4.3 等待EPOLL

  1. /**
  2. *
  3. * @param epfd 用epoll_create所创建的epoll句柄
  4. * @param event 从内核得到的事件集合
  5. * @param maxevents 告知内核这个events有多大,
  6. * 注意: 值 不能大于创建epoll_create()时的size.
  7. * @param timeout 超时时间
  8. * -1: 永久阻塞
  9. * 0: 立即返回,非阻塞
  10. * >0: 指定微秒
  11. *
  12. * @returns 成功: 有多少文件描述符就绪,时间到时返回0
  13. * 失败: -1, errno 查看错误
  14. */
  15. int epoll_wait(int epfd, struct epoll_event *event,
  16. int maxevents, int timeout);
  1. struct epoll_event my_event[1000];
  2. int event_cnt = epoll_wait(epfd, my_event, 1000, -1);

2.4 epoll API - 图3

2.4.4 epoll编程框架

  1. //创建 epoll
  2. int epfd = epoll_crete(1000);
  3. //将 listen_fd 添加进 epoll 中
  4. epoll_ctl(epfd, EPOLL_CTL_ADD, listen_fd,&listen_event);
  5. while (1) {
  6. //阻塞等待 epoll 中 的fd 触发
  7. int active_cnt = epoll_wait(epfd, events, 1000, -1);
  8. for (i = 0 ; i < active_cnt; i++) {
  9. if (evnets[i].data.fd == listen_fd) {
  10. //accept. 并且将新accept 的fd 加进epoll中.
  11. }
  12. else if (events[i].events & EPOLLIN) {
  13. //对此fd 进行读操作
  14. }
  15. else if (events[i].events & EPOLLOUT) {
  16. //对此fd 进行写操作
  17. }
  18. }
  19. }