阻塞I/O与非阻塞忙轮询I/O的缺点
阻塞I/O:一个线程只能处理一个流的I/O事件。如果想要同时处理多个流,要么多进程(fork),要么多线程(pthread_create)。
非阻塞忙轮询I/O:循环轮询所有流,没有I/O时CPU空转。
以上两种方式缺点很明显,阻塞I/O一个线程(或进程)处理一个流不适合高并发和大量长连接场景,非阻塞忙轮询I/O的主要问题需要主动轮询流的状态,无I/O时CPU空转。
非阻塞I/O及epoll理解新方式
非阻塞I/O可以理解为引入一个代理(select、poll、epoll等),这个代理比较厉害,可以同时观察许多流的I/O事件,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中醒来,由程序轮询一遍所有的流进行相应的I/O。
有两点很重要:
1、非阻塞I/O的本质,是把一个流加入到内核监控列表中,当监控列表中的流有I/O操作时,会主动推送消息给应用程序,让应用程序知道,哪个流发生了怎样的I/O事件。
2、epoll比select更好的一点是,当有I/O事件发生时,select返回的是所有监控的流,应用程序需要O(n)的无差别轮询所有流。epoll模式下内核只会返回有发生I/O事件的流并且指明发生了什么I/O事件。
补充一点:阻塞模式下,内核对于I/O事件的处理是阻塞或者唤醒,而非阻塞模式下则把I/O事件交给(代理给)其他对象(select、epoll等)处理甚至直接忽略。
参考链接
网络编程基础——学习阻塞,非阻塞(select和epoll)
http://www.cnblogs.com/Simon-xm/p/4093347.html
IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
http://blog.csdn.net/historyasamirror/article/details/5778378