进击吧,linux(十四) 无名管道编程
0赞Linux进程和进程之间有多种通讯方式。Linux进程间通讯的主要方式有:
1、无名管道
2、有名管道
3、信号
4、消息队列
5、共享内存
6、信号量
7、套接字
管道操作是比较简单的通讯方式,一个进程在管道中写入数据,另一个进程从管道中读出数据。管道包括无名管道和有名管道。前者只能用于父进程和子进程间的通信,后者可用于任意两个进程之间。
无名管道的操作,其实就是对文件的操作。无名管道一旦创建完成后,我们可以认为linux自动创建了两个文件,一个文件对应无名管道的写端,一个文件对应无名管道的读端,当然这两个文件我们是看不到的。这样操作无名管道就等同于操作文件。无名管道的读端被视作一个文件,无名管脚的写端也被视作一个文件。写管道对写端文件进行写,读管道对读端文件进行读。管道文件和普通文件的区别是管道文件读取数据后,数据就从管道文件中消失了。普通文件读取后,数据依然还是在文件中的。
以下是无名管道通信的示意图。
首先在内核中创建一个无名管道,将父进程或者子进程分别对应上读端或者写端。对于发数据的进程,就往管道写端中写数据,对于读数据的进程,就从管道读端中读数据。
同样,无名操作也是由函数操作。
主要要学习的函数是创建无名管道
5.1.1函数名
pipe
5.1.2函数原形
int pipe(int pipefd[2])
5.1.3函数功能
创建无名管道
5.1.4所属头文件
5.1.5返回值
成功:0
失败:-1
5.1.6参数说明
pipefd[2]:返回读端和写端的文件的文件描述符
pipefd[0]:无名管道的读端的文件描述符
pipefd[1]:无名管道的写端的文件描述符
无名管道创建后,会得到两个文件描述符,对应无名管道的读端和写端。那写数据和读数据就比较简单了,参照之前学习的文件操作的函数。使用read,write,close等函数来对无名管道操作即可。
以下是代码:
代码也比较简单,首先使用pipe创建无名管道,得到无名管道的读端和写端的文件描述符。然后使用fork创建子进程,因为无名管道只能是父子进程间数据通信。
在父进程中,使用pipefd[1]文件描述符,对应无名管道的写端,使用write函数,将数据写入到写端文件中。然后等待子进程读取数据,在关闭写端文件。
在子进程中,使用pipefd[0]文件描述符,对应无名管道的读端,使用read函数,将无名管道的数据读入,然后再关闭读端文件。
运行结果:
可见,无名管道写入数据和读取数据成功。
使用无名管道,要注意要在fork创建子进程前,创建无名管道,这样父子进程看到的管道才是同一个,操作的也是同一个。如果是在fork创建子进程后,创建无名管道,那就是父子进程各自创建一个管道,就实现不了通信了。