首页 > 为什么IO多路复用要搭配非阻塞IO?

为什么IO多路复用要搭配非阻塞IO?

IO多路复用的函数是阻塞的 比如 select();

当有套接口可读时, select函数就返回了, 告诉我们套接口已经可读, 然后我们去读这个套接口, 可以用阻塞的read或者非阻塞的read, 阻塞函数是无数据可读就阻塞进程, 非阻塞函数是无数据可读就返回一个EWOULDBLOCK错误. 那么问题来了: select都返回可读了, 那就表示一定能读了. 阻塞函数read也能读取了也就不会阻塞了, 非阻塞函数也有数据读了,也不会返回错误了. 那么这俩不都一样了? 为什么还得用非阻塞函数? 还有Reactor模式也是用的IO多路复用与非阻塞函数, 这是什么道理呢?


搭配非阻塞是为了提高应用的响应速度,select一样可以阻塞调用,Reactor非阻塞是他自己的架构设计。。另外read阻塞不阻塞取决于socket本身。


IO和NIO的关键就在你读取的过程中,假设一个情况,你正在读取一个数据,它的长度是500字节,但是目前传输而来的数据只有200字节,还有300在路上。这时候你有两种方式,一种是继续阻塞,等待那些数据到达。不过这显然不是个好方法,因为你不知道那些数据还有多久到达(有可能网络中断了,它们永远不会到达了)。另外一种方法是将已经读取的数据先记录到缓冲中,然后继续等待运行(一般就是再等待接口可读),等数据到达了再拼接起来。而NIO就是帮你搭建了第二种方法的基础,帮你把缓冲等问题处理好了,这样虽然两个读取都是阻塞的,但是第一种阻塞是网络IO的阻塞,第二种阻塞是本地缓冲IO的阻塞,显然第二种更有确定性、更可靠。特别实在读取数据到下一次等等套接字可读的过程中,你还需要做一些其他的响应或处理时,这个线程就要保障不能长时间阻塞,所以NIO是个很好的解决办法。

总的来说NIO只是在BIO上做一个简单封装,让你专注到实现功能中去,不用再考虑网络IO阻塞的问题。

【热门文章】
【热门文章】