管道是 Linux 中常用的进程间通信方式。Linux 中管道并非只有一种,这里介绍一下 Linux 下的
三种管道。
(匿名)管道
1 |
|
pipe()
函数创建一个匿名管道,因为是匿名的,所以并不能通过名字来获取它,也就使得
非亲缘进程间通过它进行数据传递成为了不可能,不过还有命名管道(FIFO)可以用,下文会
提到。
pipe()
接受一个长度为 2 的 int 型数组,如果调用成功,数据的第 0 和第 1 个元素会
分别放置管道的输入和输出文件描述符。在通过fork()
等系统调用创建了新的进程的时候,
会自动复制父进程中的几乎所有信息,包括这个保存管道描述符的数组,此时,进程间就可
以通过这个管道进行通信了。
一般来说,管道是单向的,如果需要进行双向通信,可以申请两个管道。下面是一个例子:
1 |
|
标准流管道
1 |
|
popen()
和pclose()
是成对出现的,由popen()
创建的管道必须使用pclose()
关闭。
第一个参数是用字符串指定的一个命令,由sh -c
来执行,第二个参数也是一个字符串,
用来指定是读取(“r”)还是写入(“w”)。举例如下:
1 |
|
命令管道(FIFO)
1 |
|
命名管道与匿名管道不同,并不随着进程的退出而消失,可以使用一般的命令进行查看,如
ls 和 cat 等。还有一个同名的命令可以创建 FIFO。mkfifo()
的参数都非常直观,不再
赘述。举例如下:
1 |
|
程序编译运行时,会阻塞在open()
处,在另一个终端里对/tmp/my_fifo
进行读取即可,
可以使用命令cat /tmp/my_fifo
,即时程序会继续执行,cat
命令会输出fifo test
字
符。
程序结束后,文件/tmp/my_fifo
不会消失,可以使用rm
或unlink
将其删除,当然也可
以在程序中将其删除,只需在最后加上一句:
1 | unlink("/tmp/my_fifo"); |