epoll系统调用

1 #include <sys/epoll.h>
2 int epoll_create(int size);//创建一个epfd,标识内核中的事件表
3 int epoll_ctl(int epfd, int op,int fd, struct epoll_event *event);//向epfd中添加,删除,修改事件
4 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);//从epfd中取出实际发生的事件

  epoll使用一组函数来完成任务,将用户感兴趣的fd上的事件放在内核里的一个事件表中,epoll使用一个额外的fd来唯一标识内核中的这个事件表。

创建一个epoll对象epfd。

int epoll_create(int size);

  size:给内核一个提示,告诉内核事件表需要多大;事件表中会维护一棵红黑树和一个双向链表,将监听的fd集合放到红黑树中,将实际发生事件的fd集合放到双向链表中。

  返回值:返回一个fd,标识内核事件表;

 

 对epoll对象进行操作,将需要监听的事件和对应的fd加到内核事件表中的红黑树。

int epoll_ctl(int epfd, int op,int fd, struct epoll_event *event);
  epfd:标识内核事件表的fd;
  op:指定操作类型,用三个宏来表示
    EPOLL_CTL_ADD-向epfd中注册fd上的事件;EPOLL_CTR_MOD-在epofd中修改fd上注册的事件;EPOLL_CTL_DEL-从epfd中删除fd上注册的事件;
  fd:需要操作(监听)的fd;
  event:epoll_event结构指针类型(含需要监听的事件类型和对应的fd),告诉内核需要监听事件类型和对应的fd。

 1 struct epoll_event
 2 {
 3     _uint32_t events; //epoll监听的的事件类型(注册的事件),一系列事件的按位或
 4     epoll_data_t data; //联合体,存储用户数据,使用最多的是fd
 5 };
 6 
 7 typedef union epoll_data
 8 {
 9     void* ptr;
10     int fd; //事件所从从属的fd,使用最多
11     uint32_t u32;
12     uint64_t u64;
13 }epoll_data_t; //联合体,同一时刻只能保存一个成员的值

  epoll的事件类型:
  E
POLLIN-数据可读;EPOLLRDNORM-普通数据可读;EPOLLRDBAND-优先级带数据可读;EPOLLPRI-高优先级数据可读;
  EPOLLOUT-数据可写;EPOLLWRNORM-普通数据可写;EPOLLWRBAND-优先级带数据可写;
  EPOLLRDHUP-TCP连接对方关闭或者对方关闭了写操作;
  EPOLLERR-错误;EPOLLHUP-挂起;EPOLLNVAL-fd没有打开;
  EPOLLET-将epoll设为边缘触发(ET)模式,另一种模式为水平触发(LT)
模式
  EPOLLONESHOT-只监听一次事件,监听结束后,如果要继续监听事件对应的fd,需要将这个fd再次加入到epoll队列中。

  返回值:调用成功,返回0;调用失败,返回-1。

  监听(注册)的事件中实际发生的事件,epoll_wait函数如果检测到就绪事件,就将就绪事件从epfd标识的内核事件表中的双向链表中复制到events指向的数据结构中(仅含检测到的就绪事件)。

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);  epfd:标识内核事件表的fd;

  events:epoll_event结构类型的链表(链表的的数据域为结构体),实际发生的事件;
  maxevents:监听fd的数量;
  timeout:设置epoll的超时时间,单位为毫秒;
  返回值:timeout=0,epoll_wait调用立即返回,非阻塞;timeout=-1,epoll_wait
调用阻塞,直到某个事件发生。
调用成功,返回就绪的fd的数量;调用失败,返回-1并设置errno。
  


LT模式和ET模式
  采用LT模式的fd,当应用程序调用epoll_wait检测到fd上有事件发生,将发生的事件通知应用程序,应用程序可以不立刻处理该事件,当应用程序下次调用epoll_wait时,epoll_wait会继续将发生的事件通知应用程序,知道该事件被处理;

  采用LT模式的fd,当应用程序调用epoll_wait检测到fd上有事件发生,将发生的事件通知应用程序,应用程序必须立刻处理该事件,当应用程序再次调用epoll_wait是,将不再将发生的事件通知应用程序。

  相比LT模式,ET模式减少了事件被重复触发的次数,效率较高。

 

   

 

  

posted @ 2021-01-30 18:47  封狼居胥!  阅读(263)  评论(0编辑  收藏  举报