多路IO复用模型 select epoll
来源:互联网 发布:旅游旅行知乎 编辑:程序博客网 时间:2024/05/11 15:20
同步阻塞IO在等待数据就绪上花去太多时间,而传统的同步非阻塞IO虽然不会阻塞进程,但是结合轮询来判断数据是否就绪仍然会耗费大量的CPU时间。
多路IO复用提供了对大量文件描述符进行就绪检查的高性能方案。
select
select诞生于4.2BSD,在几乎所有平台上都支持,其良好的跨平台支持是它的主要的也是为数不多的优点之一。
select的缺点(1)单个进程能够监视的文件描述符的数量存在最大限制(2)select需要复制大量的句柄数据结构,产生巨大的开销 (3)select返回的是含有整个句柄的列表,应用程序需要遍历整个列表才能发现哪些句柄发生了事件(4)select的触发方式是水平触发,应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。相对应方式的是边缘触发。
poll
poll 诞生于UNIX System V Release 3,那时AT&T已经停止了UNIX的源代码授权,所以显然也不会直接使用BSD的select,所以AT&T自己实现了一个和select没有多大差别的poll。
poll和select是名字不同的孪生兄弟,除了没有监视文件数量的限制,select后面3条缺点同样适用于poll。
面对select和poll的缺陷,不同的OS做出了不同的解决方案,可谓百花齐放。不过他们至少完成了下面两点超越,一是内核长期维护一个事件关注列表,我们只需要修改这个列表,而不需要将句柄数据结构复制到内核中;二是直接返回事件列表,而不是所有句柄列表。
/dev/poll
Sun在Solaris中提出了新的实现方案,它使用了虚拟的/dev/poll设备,开发者可以将要监视的文件描述符加入这个设备,然后通过ioctl()来等待事件通知。
/dev/epoll
名为/dev/epoll的设备以补丁的方式出现在Linux2.4中,它提供了类似/dev/poll的功能,并且在一定程度上使用mmap提高了性能。
kqueue
FreeBSD实现了kqueue,可以支持水平触发和边缘触发,性能和下面要提到的epoll非常接近。
epoll
epoll诞生于Linux 2.6内核,被公认为是Linux2.6下性能最好的多路IO复用方法。
- epoll_create 创建 kernel 中的关注事件表,相当于创建 fd_set
- epoll_ctl 修改这个表,相当于 FD_SET 等操作
- epoll_wait等待 I/O事件发生,相当于 select/poll 函数
epoll支持水平触发和边缘触发,理论上来说边缘触发性能更高,但是使用更加复杂,因为任何意外的丢失事件都会造成请求处理错误。Nginx就使用了epoll的边缘触发模型。
这里提一下水平触发和边缘触发就绪通知的区别,这两个词来源于计算机硬件设计。它们的区别是只要句柄满足某种状态,水平触发就会发出通知;而只有当句柄状态改变时,边缘触发才会发出通知。例如一个socket经过长时间等待后接收到一段100k的数据,两种触发方式都会向程序发出就绪通知。假设程序从这个socket中读取了50k数据,并再次调用监听函数,水平触发依然会发出就绪通知,而边缘触发会因为socket“有数据可读”这个状态没有发生变化而不发出通知且陷入长时间的等待。
因此在使用边缘触发的 api 时,要注意每次都要读到 socket返回 EWOULDBLOCK为止
- 多路IO复用模型 select epoll
- 多路IO复用模型 select epoll 等
- 多路IO复用模型 select epoll 等
- Unix IO 复用模型之 select & poll & epoll
- Epoll多路IO复用模型
- IO复用函数select poll epoll
- select poll epoll的io模型
- IO模型和Select/Poll/Epoll解析
- select,epoll 多路IO复用
- IO模型及多路复用IO(select、poll、epoll)
- Linux系统IO复用接口(select、poll、epoll)
- Linux系统IO复用接口(select、poll、epoll)
- IO复用函数--Select,poll,epoll的比较
- IO复用之select poll epoll的总结
- IO复用之select poll epoll 函数
- Linux下select, poll和epoll IO模型的详解
- IO模型及select、poll、epoll和kqueue的区别
- Linux下select, poll和epoll IO模型的详解
- (Android 基础知识) ActionBar----顶部控件
- Protocol Buffer技术详解(Java实例)
- 如何避免自己发出的邮件被误判为垃圾邮件
- C++ 用socket封装成http
- 一篇鞭策程序员的短文:我们这一代的汽车工人
- 多路IO复用模型 select epoll
- fusionchars报表插件的使用
- HTML5-页面多页面滑动
- spring mvc @Qualifier注解接口来注入 @Service
- 类集框架的简单示例
- Android Maps app开源,邀请开发者共同参与
- 今天开始学习《30天自制操作系统》
- c语言实现字符串字串的替换
- 关闭oralce的进程oracle.exe,怎么再重新打开进程oracle.exe