Linux下的进程通信方式之有名管道
Linux下的通信方式之有名管道
前言
我们知道,对于匿名管道来说,其只可以用于具有共同祖先的两个进程中。所以出现了有名管道,它可以用于没有血缘关系的进程间通信。
有名管道的特点是:
- FIFO是以命名文件的形式存在,而不是打开的文件描述符,所以在对它进行读写操作之前必须先打开它。而且,对于FIFO来说,传递给open函数的第一个参数一定是一个FIFO的路径名,而不是一个文件名。
非阻塞 I/O
我们知道,如果打开一个另一端没有被打开的 FIFO 的时候,那么读写操作会阻塞。但是,有名管道还支持非阻塞 I/O。
如果在打开 FIFO 后,使用 O_NONBLOCK 标志,就是也非阻塞的方式打开 FIFO。
1 |
|
只有当 FIFO 的另一端还没有被打开的时候 O_NONBLOCK
标记才会起作用,而具体产生的影响则依赖于打开 FIFO 是用于读取还是用于写入的。
非阻塞的 write() 和 read()
由于我们是使用 open() 函数中的 flag 来打开的文件,所以实际上这个 O_NONBLOCK
还会影响到 write()
和 read()
函数。
我们可以通过下面的代码来实现再开关 O_NONBLOCK
标志:
管道和 FIFO 中 read()和 write()的语义
从上面我们可以知道,在打开了 O_NONBLOCK
标志之后,如果写入的数据小于 PIPE_BUF
的值,则要么是直接写入,要么是返回 EAGAIN
错误。
总结
通过上面的描述,我们知道:
O_NONBLOCK 标记对于在打开 FIFO 时不希望阻塞来讲是有用的,同时对读取操作在没有数据可用时不阻塞或在写入操作在管道或 FIFO 没有足够的空间时不阻塞也是有用的。
注意:PIPE_BUF是系统对FIFO的一个数据长度的限制,通常在头文件limits.h可以找到它,通常值为4096字节,也有特例。系统规定:在一个以O_WRONLY方式(即阻塞方式)打开的FIFO中,如果写入的数据长度小于等于PIPE_BUF,要么全部一次性写入,要么一个字节也不写入。
基于“注意”中的描述,如果出现一种情况:多个程序向一个FIFO中写入数据的时候,为了保证这些写入的数据不会相互交错重叠,那么就要求每次写入的数据长度要小于等于PIPE_BUF字节。