weiqi7777

进击吧,linux(十四) 无名管道编程

0
阅读(2591)

Linux进程和进程之间有多种通讯方式。Linux进程间通讯的主要方式有:

1、无名管道

2、有名管道

3、信号

4、消息队列

5、共享内存

6、信号量

7、套接字

管道操作是比较简单的通讯方式,一个进程在管道中写入数据,另一个进程从管道中读出数据。管道包括无名管道和有名管道。前者只能用于父进程和子进程间的通信,后者可用于任意两个进程之间。

无名管道的操作,其实就是对文件的操作。无名管道一旦创建完成后,我们可以认为linux自动创建了两个文件,一个文件对应无名管道的写端,一个文件对应无名管道的读端,当然这两个文件我们是看不到的。这样操作无名管道就等同于操作文件。无名管道的读端被视作一个文件,无名管脚的写端也被视作一个文件。写管道对写端文件进行写,读管道对读端文件进行读。管道文件和普通文件的区别是管道文件读取数据后,数据就从管道文件中消失了。普通文件读取后,数据依然还是在文件中的。

以下是无名管道通信的示意图。

clip_image002

首先在内核中创建一个无名管道,将父进程或者子进程分别对应上读端或者写端。对于发数据的进程,就往管道写端中写数据,对于读数据的进程,就从管道读端中读数据。

同样,无名操作也是由函数操作。

主要要学习的函数是创建无名管道

5.1创建无名管道

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等函数来对无名管道操作即可。

以下是代码:

clip_image004

代码也比较简单,首先使用pipe创建无名管道,得到无名管道的读端和写端的文件描述符。然后使用fork创建子进程,因为无名管道只能是父子进程间数据通信。

在父进程中,使用pipefd[1]文件描述符,对应无名管道的写端,使用write函数,将数据写入到写端文件中。然后等待子进程读取数据,在关闭写端文件。

在子进程中,使用pipefd[0]文件描述符,对应无名管道的读端,使用read函数,将无名管道的数据读入,然后再关闭读端文件。

运行结果:

clip_image005

可见,无名管道写入数据和读取数据成功。

使用无名管道,要注意要在fork创建子进程前,创建无名管道,这样父子进程看到的管道才是同一个,操作的也是同一个。如果是在fork创建子进程后,创建无名管道,那就是父子进程各自创建一个管道,就实现不了通信了。

Baidu
map