对epoll不支持磁盘IO这件事,很长一段时间都是只知道结论,但是从来没搞清楚原因,网上找了一些中文的解释都让人看的云里雾里。最近在查找资料的时候,无意中发现如果自己按照“DISK Io”这样的方式去搜索英文资料,那可能不会找到想要的答案,因为在linux官方的叫法中,磁盘文件准确的称呼应该是“regular files”。然后我按照“epoll regular files”的方式得到的内容一下多了许多。最后也是得到了比较满意的答案,这里写出来分享一下。
阻塞和非阻塞
首先在谈论epoll不支持磁盘IO文件之前,先理清阻塞和非阻塞指的阶段是什么,我们在讨论IO操作阻塞非阻塞时,是指当你发起一个IO操作后,如果IO没有准备好,你的线程是否要停留在那里等待IO准备好。这里特别说明了只是说等待io准备好,系统真正开始io操作的时候,虽然也有耗时,但是那并不算讨论阻塞非阻塞的范畴。
接着在说回到磁盘IO这件事上,虽然linux的哲学是一切都是文件,磁盘和网络的读写都可以理解为文件的读写,但是文件和文件还是有不同的。比如说你并不能对一个磁盘文件描述符设置非阻塞,但是可以对一个网络io设置非阻塞。理解这事的核心点是理解阻塞发生的原因, 既你向操作系统发起io操作的时候,IO还没有准备好,比如在读请求的时候,缓冲区里的数据不够,或者在执行写操作的时候,缓冲区满了,这对网络来说是常态,因为你根本不确定网络连接的另一头到底什么时候会和你收发数据,所以默认阻塞是常态,然后才为了可以让你的程序不用傻等在这里,才设计了非阻塞。但是对于磁盘来说,根本就没有等待可读或可写一说,因为它一直是就绪的,始终可读可写,POSIX规范中明确指出了这一点。我猜测是设计者当时也觉得给磁盘文件io设置非阻塞没什么意义。