linux进程通信之命名管道

命名管道本质上是个特殊的文件,可以通过shell的mkfifo命令,或者程序的mkfifo( ) 函数来创建这种特殊文件,相关信息可以分别通过shell中的命令来查看:man 1 mkfifo 和  man 3 mkfifo

shell命令:man 7 fifo指出:

(1)多个进程通过fifo交换数据时,数据并没有真的被写入文件系统,因此文件系统中的fifo文件里面什么内容都没有。

(2)只有fifo在读写端都被打开时,两个进程才能通过这个fifo交换数据

(3)一个进程可以以非堵塞模式打开fifo,这时,即使写端没有打开,读端试图以只读方式打开fifo,也会成功;但是反过来,如果读端没有打开fifo,写端试图以只写的方式打开fifo,会失败,同时发出管道破裂信号SIGPIPE。

(4)在linux下,以读写模式打开fifo时,不论是堵塞模式打开,还是非堵塞模式打开,都会成功。这一特性解决了上面(3)中提到的一个不足,当读端没有打开时,在写端我们可以通过读写的方式成功打开这个fifo,这样就不会打开失败了

(5)一个进程可以通过一个fifo自己跟自己通信,但是一定要小心,这种用法很容易造成死循环


mkfifo函数的原型为:int mkfifo(const char *pathname, mode_t mode);

(1)形参:@pathname,设定的文件路径+文件名,文件必须不存在,若已存在,则本函数出错;

@mode,创建的文件的属性,其意义和open函数的mode形参相同,可取以下三个按位或的值:O_RDONLY、O_WRONLY、 O_RDWR,一般可取0666

(2)返回:正常返回0,出错返货-1并设置errno

(3)通过命名管道fifo进行通信,和读写普通文件没什么两样,然而,在读写之前,程序员必须保证管道文件在读端和写端都已经被打开

(4)读操作可能会被堵塞,直到另一个进程以写的方式打开同一个fifio


关于原子性:

当试图写入的字节数≤PIPE_BUF时,内核可以保证写入的原子的,对于堵塞和不堵塞两种情况,保证原子的方法是不同的:堵塞模式下,fifo的剩余空间不足以容纳数据,那么程序会等待fifo,一旦fifo可以容纳要写的数据,那就一次性写入;非堵塞模式下,如果fifo的剩余空间不足以容纳数据,那么就出错返回并设置errno,如果可以容纳,那自然一下子就写成功了。

当试图写入的字节数>PIPE_BUF时,内核不保证写入原子性。


命名管道设置堵塞或者不堵塞,可以在open时通过形参flag来设定。

样例程序就不贴了,和读写文件一样。

猜你喜欢

转载自blog.csdn.net/qq_31073871/article/details/80891231