Linux下的进程通信方式之有名管道

Linux下的通信方式之有名管道

前言

我们知道,对于匿名管道来说,其只可以用于具有共同祖先的两个进程中。所以出现了有名管道,它可以用于没有血缘关系的进程间通信。

有名管道的特点是:

  • FIFO是以命名文件的形式存在,而不是打开的文件描述符,所以在对它进行读写操作之前必须先打开它。而且,对于FIFO来说,传递给open函数的第一个参数一定是一个FIFO的路径名,而不是一个文件名。

非阻塞 I/O

我们知道,如果打开一个另一端没有被打开的 FIFO 的时候,那么读写操作会阻塞。但是,有名管道还支持非阻塞 I/O。

如果在打开 FIFO 后,使用 O_NONBLOCK 标志,就是也非阻塞的方式打开 FIFO。

1
2
3
fd = open(FIFO_NAME, O_RDWR | O_NONBLOCK);
if(fd == -1)
exit(-1);

只有当 FIFO 的另一端还没有被打开的时候 O_NONBLOCK 标记才会起作用,而具体产生的影响则依赖于打开 FIFO 是用于读取还是用于写入的。

非阻塞的 write() 和 read()

由于我们是使用 open() 函数中的 flag 来打开的文件,所以实际上这个 O_NONBLOCK 还会影响到 write()read() 函数。

我们可以通过下面的代码来实现再开关 O_NONBLOCK 标志:

管道和 FIFO 中 read()和 write()的语义

从上面我们可以知道,在打开了 O_NONBLOCK 标志之后,如果写入的数据小于 PIPE_BUF 的值,则要么是直接写入,要么是返回 EAGAIN 错误。

总结

通过上面的描述,我们知道:

  1. O_NONBLOCK 标记对于在打开 FIFO 时不希望阻塞来讲是有用的,同时对读取操作在没有数据可用时不阻塞或在写入操作在管道或 FIFO 没有足够的空间时不阻塞也是有用的。

  2. 注意:PIPE_BUF是系统对FIFO的一个数据长度的限制,通常在头文件limits.h可以找到它,通常值为4096字节,也有特例。系统规定:在一个以O_WRONLY方式(即阻塞方式)打开的FIFO中,如果写入的数据长度小于等于PIPE_BUF,要么全部一次性写入,要么一个字节也不写入。

  3. 基于“注意”中的描述,如果出现一种情况:多个程序向一个FIFO中写入数据的时候,为了保证这些写入的数据不会相互交错重叠,那么就要求每次写入的数据长度要小于等于PIPE_BUF字节。


Linux下的进程通信方式之有名管道
https://ysc2.github.io/ysc2.github.io/2024/08/16/Linux下的进程通信方式之有名管道/
作者
Ysc
发布于
2024年8月16日
许可协议