在打开文件时指定O_NONBLOCK标志,目的有二
- 如果open()调用未能立即打开文件,则返回错误,而非陷入阻塞。有一种情况属于例外,调用open()操作FIFO可能会陷入阻塞
- 调用 open()成功后,后续的 I/O 操作也是非阻塞的。若 I/O 系统调用未能立即完成,则可能会只传输部分数据,或者系统调用失败,并返回 EAGAIN 或 EWOULDBLOCK 错误。具体返回何种错误将依赖于系统调用。Linux 系统与许多 UNIX 实现一样,将两个错误常量视为同义。
管道、FIFO、套接字、设备(比如终端、伪终端)都支持非阻塞模式(因为无法通过open()来获取管道和套接字的文件描述符,所以要启用非阻塞标志,就必须使用fcntl的F_SETFL命令)。
另外,由于内核缓存区保证了普通文件IO不会陷入阻塞,因此打开普通文件时一般会忽略O_NONBLOCK标志。但是,当使用强制文件锁时,O_NONBLOCK标志对普通文件也是起作用的。
历史上,派生自 System V 的系统提供有 O_NDELAY 标志,语义上类似于 O_ NONBLOCK标志。二者主要的区别在于:
- 在 System V 系统中,若非阻塞的 write()调用未能完成写操作,或者非阻塞的 read()调用无输入数据可读时,则两个调用将返回 0。这对于 read()调用来说会有问题,因为程序将无法区分返回 0 的 read()到底是没有可用的输入数据,还是遇到了文件结尾
- 故而 POSIX.1 标准在初版中引入了 O_NONBLOCLK 标志。有些UNIX 实现一直还在支持旧语义的 O_NDELAY 标志。Linux 系统虽然也定义了 O_NDELAY常量,但其与 O_NONBLOCK 标志同义。