进程间管道通信(管道通信代码)

生活 0 584

进程间管道通信(管道通信代码)

由于各个进程之间独享一块用户地址空间,一般而言这块独立的用户地址空间不能互相访问,所以进程之间想要通信必须通过内核空间(每个进程共享)。

进程间的通信方式主要有以下几种:

管道 消息队列 共享内存 信号量 信号

Socket

管道

管道的数据传输方向是单向的,如果两个进程之间需要互相传递数据,那么需要创建两个管道才可以。

管道主要分为: 匿名管道 命令管道

匿名管道

匿名管道只适合具有父子关系的进程间通信,创建需要通过下面的系统调用来实现:

int pipe(int fd[2])

这里表示创建一个匿名管道,并返回了两个描述符,fd[0]是管道读取端描述符,fd[1]是管道写入端描述符。匿名管道只存在于内存中,不存在于文件系统。

这里的管道就是内核里面的一串缓存。管道传输的数据无格式但是大小受限。

父子进程间如何使用匿名管道通信

我们需要通过fork来创建子进程,创建的子进程会复制父进程的文件描述符,这样父子进程之间都会有fd[0]和fd[1],父子进程通过各自的fd写入和读取同一个管道文件就可以实现跨进程通信。

由于父子进程都可以对管道进行读写,为了避免这种情况的发生,通常我们会做以下操作:

父进程关闭读取的fd[0],只保留写入的fd[1]

子进程关闭写入的fd[1],只保留读取的fd[0]

所以如果需要进行双向通信,必须要建立两个管道。

shell中的A|B管道操作有什么特别?

ps aux | grep mysql

Linux上述命令|是一个管道,它的功能是将前一个命令的输出当做后一个命令的输入。但是在执行上述命令(A|B)时,由于A进程和B进程都是由shell创建出来进程,A和B之间不存在父子关系,它们父进程都是shell。它的管道读写图如下:

命名管道

命名管道可以在不相关的进程之间能互相通信,因为命令管道需要提前创建一个类型为管道的设备文件,在进程里只要使用这个设备文件,就可以互相通信。

创建管道文件

mkfifo test_pipe

向管道写入数据

echo "hello pipe" > test_pipe

在写入数据以后,命令停在此处,是因为管道里的内容没有被读取,只有当管道里的命令被读取以后,命令才可以正常退出。

读取管道命令

cat test_pipe

可以看到在执行cat读取命令以后,内容被读取出来打印在终端上,另一方面写入指令echo也正常退出。

相关推荐: