epoll边缘与水平触发简析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28666081/article/details/85228426
kqueue原理
    数据量,每    来一个数据包网卡都会中断一次。数据量很大,多次数据合并,让网卡做终端合并。数据量超大,直接忙轮询。
 
 
四个I/O事件(内核缓冲区)
    缓存区非空:刚开始内核缓冲区为空,B作为读出方被阻塞着。这时A往管道写入后,缓冲区变为非空状态。内核产生事件唤醒B。
    缓存区满:唤醒B后,B却没读出数据,且内核规定不能把写入管道的数据丢弃,A写入的数据就会滞留在内核缓冲区,直到内核缓冲区填满,就会通知A等等(即是阻塞)。
    缓冲区非满:后来B开始读数据,内核缓冲区有空出来,通知A开始写数据。
    缓冲区空:A没继续写入数据,B读取数据直到为空,阻塞。
 
但是使用上面方式会造成阻塞,一个进程/线程仅能处理一个流的I/O事件,可使用非阻塞忙轮询I/O方式,这样可以同时处理多个流:
while true {
    for i in stream[]; {
    if i has data
            read until unavailable
    }
}
忙轮询会将所有流从头到尾问一遍,如果所有流没数据,造成CPU空转,浪费CPU。
 
避免CPU空转
    引入代理select/poll,观察许多流I/O事件,空闲时阻塞当前线程,当有流有I/O事件时,从阻塞醒来并轮询一遍所有的流。
while true {
  select(streams[])    //没I/O事件就会阻塞在这里
  for i in streams[] {
            if i has data
                  read until unavailable
    }
}
 
但是select是无差别轮询,O(n)越大,处理流越多,时间越长,这时可使用epoll。
 
epoll  
while true {
    active_stream[] = epoll_wait(epollfd)
    for i in active_stream[] {   //仅运行活跃的流
        read or write till unavailable
    }
}
 
 
epoll流程    
      epoll 函数 
  • int epoll_create(int size);
  • int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
  • int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
    A. create创建一个新epoll对象,eopll_ctl 操作epoll句柄(如 将新建立socket加入到epoll,或移除正在监控的socket)。epoll_wait 调用时,在超时时间内,当监控的句柄有事件发生时,就返回用户态进程。
 
    epoll 高效的原因
        调用create时,内核在epoll文件系统建立个file节点,还在内核cache建了个红黑树用于存储epol_ctl传来的socket,另外建立一个list链表存准备就绪的事件。
        epoll_wait只需观察list链表有没数据即可,拷贝到用户态内存。
    注:一棵红黑树,一张准备就绪句柄链表,少量的内核cache
 
    epoll 水平触发和边缘触发的实现:
        水平触发:被监控的文件描述符有可读写事件发生时,epoll_wait通知处理程序处理,如果数据没有一次性读完(读写缓冲区过小),再次调用epoll_wait,会在没读完的文件描述符继续读写,如果一直不读,就一直通知。缺点:系统含大量不需读写就绪文件,但每次返回,会降低检索自己关心的就绪文件的效率。
        边缘触发: epoll_wait通知程序去读写时,如果没读写完,再次调用epoll_wait不会通知(仅会通知一次),直到文件描述符出现第二次可读写事件才会通知。效率高,不用理会不关心的就绪文件。
Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发
 
:文件描述符:在系统打开文件后用来唯一标志文件的一个结构体,类似PCB
 
 
更多待续~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·
 
 
 

猜你喜欢

转载自blog.csdn.net/qq_28666081/article/details/85228426