首页 > IT职业 > IT职场 > 操作系统I/O模型及轮询技术演变
本来是想要介绍Node.js的轮询技术,但是在这之前先了解下操作系统I/O模式的演进,有助于之后的一些理解,操作系统对于I/O的处理通常是有两步
Github技术博客: Node.js技术栈
I/O复用轮询技术select和epoll的区别?,参考:#
从应用程序开始系统调用->数据就绪,进行拷贝->拷贝结束,这之间应用程序都处于等待状态,不能做其它事情,直到将数据拷贝到用户空间或出错才返回,我们称之为阻塞I/O模式。

相比于同步阻塞I/O模式,同步非阻塞I/O在每次调用之后,如果数据没有就绪就会立即返回,之后重复调用来检查I/O操作是否就绪,这对CPU资源是一个极其浪费的操作,直到数据就绪将数据从内核拷贝到用户空间,返回成功指示给到应用程序。
Read:就是一种实现,通过重复轮询I/O来判断。

链接(Socket)并发大的情况,上面两种就不适合了,前面一个处理不完,后面就只能干等,这里就用到了I/O多路复用,下图所示相比较前两种,分为了两步,先进行select数据就绪后,在调用recvfrom进行真正的I/O读写操作。它的高级之处还在于能够一个线程同时处理多个Socket。

I/O多路服用有多种实现模式:select、poll、epoll、kqueue
通过轮询检查在文件描述符上设置的标识位来进行判断,Select的轮询相当于在数据库中查找一条记录没有建立索引,对所有的Socket进行全部遍历,这对CPU是浪费的。另外Select还有一个限制,对于单个进程所能打开的文件描述符最大只能是1024,那么基于Select的轮询技术最多也只能很好的处理1000并发的吞吐量,可以查看上一个10年,著名的C10K并发连接问题
poll和select在实现上没有本质的区别,相比较select,poll基于链表来实现,没有了最大链接1024的限制。但是当文件描述符多了之后,每次调用都会对链接进行线性遍历,性能还是十分低下的。
是linux下效率最高的I/O事件通知机制,没有最大链接限制,通过callbak回调通知机制,不在是每次调用都对链接进行线性遍历,这样就不会随着文件描述符的增加导致效率下降。
在1GB内存的机器上能监听大约10万个端口,远超过select的1024限制,具体可以在服务器上查看cat /proc/sys/fs/file-max
与epoll类似,仅存于FreeBSD(一种类UNIX操作系统)。
仅在Unix上支持,与I/O多路复用相比避免了select的阻塞轮询。应用程序进行系统调用后立即返回,处理其它事物,在数据就绪之后系统会发送一个SIGIO信号到应用程序,应用进程开始读取数据。

异步I/O模型是目前最理想的一种形式,应用程序发起系统调用后无需等待直接返回当前调用状态,进行后续的其它任务,结果由内核完成I/O操作之后通过回调通知到我们的应用程序,中间没有阻塞过程。
在Linux2.6之后增加了异步I/O的实现方式 AIO,但是很少系统能够实现。

如果问到轮询技术的实现一般也会考察select和epoll的区别
白话风格(小明与妹子的邂逅)讲解操作系统I/O模型及轮询技术演变
故事标题:小明与妹子的邂逅情节介绍:小明在校园一次文艺晚会上邂逅了一位妹子,在只得知妹子名字、手机号的情况下,经过几天的苦苦追寻,历经千山万水,终得美人归!演员介绍:男一号@小明、女一号@妹子、串场@门卫大爷
小明电话相约妹子在校门口,然后小明很专一、不见到妹子不回家,期间没有做任何事情,一直在等待!
小明电话相约妹子在校门口,妹子还没准备好(出门前化妆几小时。。。),这时候的小明很执着,每隔一会儿给妹子发个信息直到妹子准备好了。
I/O多路复用模式
信号驱动I/O模式
小明电话相约妹子在校门口,此时妹子回复说我还没准备好(出门前化妆几小时。。。),这个时候小明也没去,而是先去干其它事情了,等妹子准备好之后电话通知小明,我已经准备好了,小明这个时候才去校门口等着和妹子的约会。
小明告诉妹子我们在校园门口相约,之后小明没有在那干等了,而是先回宿舍休息会或者和朋友在打会球等等,妹子到校门口之后电话通知小明,我已经来啦。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3050/viewspace-2822656/ ,如需转载,请注明出处,否则将追究法律责任。