概述流水线是UNIX系统IPC最古老的形式,所有的UNIX系统都提供这种通信方式。所谓管道就是内核中的一串缓存。从一段管道写出来的数据,其实是缓存在内核中的,这样一端读取,也就是从内核中读取这段数据。流水线数据是一个大小有限的无格式流。对于管道,也分为匿名管道和命名管道。命名管道也称为FIFO。下面分别介绍两种管道。默认情况下,在Shell命令执行过程中,任何命令都有标准输入设备(键盘)、标准输出设备(显示器)和标准输出设备(显示器),使用管道符“|”连接两个命令连接改变标准输入输出方式,下面是Linux端运行的命令行截图:上面命令的意思是将ls命令得到的结果作为输入grep标签命令。连接输入和输出的中间设备是管道文件。综上所述,一个命令的输出可以作为另一个命令的输入(运行时,一个命令会创建一个进程),而这个管道是临时的,命令执行完后会自动消失。这种类型的管道称为无名管道。匿名管道示例匿名管道在使用前必须先创建,其函数声明如下:externintpipe(int__pipedes[2]);这个函数的参数是一个整型数组。如果执行成功,pipe会存储两个整数文件描述符在__pipedes[0]和__pipedes[1]中,它们分别指向管道的两端。如果系统调用失败则返回-1。读取一个无名管道,这个函数的声明如下:externssize_tread(int__fd,void*__buf,size_t__nbytes);第一个参数fd是打开的文件描述符,buf是读取数据的存储位置,nbytes是读取数据的大小,调用read函数会宏从指向的文件描述符指定的打开文件中读取n个字节fd到buf指向的缓冲区。如果你试图写入一个已经满的管道,系统会自动阻塞。一个管道不能同时被两个进程打开。externssize_twrite(int__fd,__constvoid*__buf,size_t__n);从buf指向的buffer中写入nbytes个字节到管道中,每写入的内容追加到管道的末尾。那么两个进程之间如何使用管道进行通信呢,我们可以使用fork()创建子进程,创建的子进程会复制父进程的文件描述符,这样两个进程就有两个fd[0]和fd[1],两个进程可以通过各自的fd读写同一个管道文件,实现进程通信,具体原理如下:具体例子如下:#include#include#includeintmain(intargc,char*argv[]){pid_tpid;inttemp;intpipedes[2];chars[14]="testmessage!";chard[14];if(pipe(pipedes)==-1)//创建管道{perror("pipe");exit(EXIT_FAILURE);}if(pid==fork()==-1){perror("fork");exit(EXIT_FAILURE);}elseif(pid==0)//子进程{printf("now,writedatatopipe\n");if(write(pipedes[1],s,14)==-1)//写入数据管道{perror("write");exit(EXIT_FAILURE);}else{printf("thewrittendatais:%s\n",s);exit(EXIT_SUCESS);}}elseif(pid>0)//父进程{slepp(2);printf("now,readfrompipe\n");if((read(pipedes[0],d,14))==-1){perror("read");exit(EXIT_FAILURE);}printf("thedatafrompipeis:%s\n",d);}return0;}代码运行结果如下:Namedpipe命名管道也叫FIFO,unnamedpipe只能连接在两个相关的pipe之间使用进程之间,并且两个相关进程必须一起创建它们的祖先进程,但是,通过FIFO,不相关的进程也可以交换数据。首先介绍一下如何创建命名管道:externintmkfifo(__constchar*__path,__mode_t__mode);mkfifo会根据参数创建一个特殊的命名管道文件。文件必须不存在,参数mode为文件权限。下面是一个使用命名管道进行进程间通信的例子。例子分为两个程序,分别是阅读部分和写作部分。首先,先看向管道写入数据的代码。代码如下:#include#include#include#include#include#includeintmain(){intfd;//FIFOfilepathchar*myfifo="/tmp/myfifo";//创建命名文件(FIFO)//mkfifo(,)mkfifo(myfifo,0666);chararr1[80],arr2[80];while(1){//OpenFIFOforwriteonlyfd=open(myfifo,O_WRONLY);printf("Thefdis:%d\n",fd);//Takeaninputarr2ingfromuser.//80ismmaximumlengthfgets(arr2,80,stdin);//Writetheinputarr2ingonFIFO//andcloseitwrite(fd,arr2,strlen(arr2)+1);close(fd);//OpenFIFOforReadonlyfd=open(myfifo,O_RDONLY);//ReadfromFIFOread(fd,arr1,sizeof(arr1));//Printthereadmessageprintf("User2:%s",arr1);close(fd);}return0;}然后是从管道中读取数据的代码,代码如下:#include#include#include#include#include#include