使用 O_NONBLOCK 模式会影响到对 FIFO 的 read 和 write 调用。
对一个空的、阻塞的 FIFO (即没有用 O_NONBLOCK 标志打开)的read 调用将等待,直到有数据可以读时才继续执行。于此相反,对一个空的、非阻塞的 FIFO 的 read 调用将立刻返回 0 字节。
对一个完全阻塞 FIFO 的 write 调用将等待,直到数据可以被写入时才继续执行。对于非阻塞的 FIFO,如果 FIFO 不能接收所有写入的数据,它将按下面的规则执行。
- 如果请求写入的数据长度小于等于 PIPE_BUF 字节,调用失败,数据不能写入。
- 如果请求写入的数据的长度大于 PIPE_BUF 字节,将写入部分数据,返回写入 FIFO 的字节数,返回值也可能是0。
FIFO 的长度是需要考虑的一个很重要的因素。系统对任一时刻在一个 FIFO 中可以存在的数据长度是有限制的。它由 #define PIPE_BUF 语句定义,通常可以在头文件 limits.h 中找到它。在linux和许多其他类UNIX系统中,它的值通常是 4096 字节,但在某些系统中它可能会小到 512 字节。系统规定,在一个以 O_WRONLY 方式(即阻塞方式)打开的 FIFO 中,如果写入的数据长度小于等于 PIPE_BUF,那么或者全部写入全部字节,或者一个字节都不写入。
虽然,对只有一个 FIFO 写进程和一个 FIFO读进程的简单情况来说,这个限制并不是非常重要,但只适用一个 FIFO并允许多个不同的程序向一个 FIFO读进程发送请求的情况是很常见的。如果几个不同的程序尝试同时向 FIFO 写数据,能保证来自不同程序的数据块不想互交错就非常关键了。也就是说每个写操作都必须是“原子化”的。
如果能保证所有的写请求是发往一个阻塞的 FIFO 的,并且每个写请求的数据长度小于等于 PIPE_BUF 字节,系统就可以确保数据绝不会交错在一起。通常将每次通过 FIFO 传递的数据长度限制为 PIPE_BUF 字节是个好办法,除非只使用一个写进程和一个读进程。