• 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模式减少了事件被重复触发的次数,效率较高。

     

       

      

  • 相关阅读:
    Django_redis_session
    python_redis操作
    Django_url反向解析
    Django_分页
    Django_cookie与sesstion
    Django 自定义错误页面 403 404...
    Django_设置静态文件、上传文件
    Django设置子路由
    nginx、uwsgi
    CentOS安装MySQL
  • 原文地址:https://www.cnblogs.com/yongjin-hou/p/14350023.html
Copyright © 2020-2023  润新知