一、进程间通信一系统介绍进程间通信进程间通信IPC介绍小编插入的这篇文章详细介绍了进程间通信的一些内容大家可以一起学习。二进程间通信的方法1、管道2、信号量3、共享内存4、消息队列5、套接字接下来的几篇文章小编就会按照顺序介绍这几种方法加粗的为重点内容今天首先要学到的是管道。二、管道关于管道这个词其实我们在之前有过一点点了解不知道大家还是否记得。在Linux四基础命令2中| 代表管道当时是和grep过滤搭配使用。今天我们就正式接触管道这个内容了。首先是管道的分类分为有名管道命名管道和无名管道。它们的区别是有名管道在任意两个进程间通信无名管道在父子进程之间通信。一有名管道1、创建有名管道 mkfifo2、打开管道 open()3、关闭管道 close()4、读数据 read()5、写入数据 write()在学习完上面的操作后我们来思考一个问题如果进程a要从键盘获取数据传递给另一个进程b不使用管道操作应该如何完成其实在C语言中我们可以通过文件操作完成但是通过文件进行进程间通信存在两个问题1速度慢2读数据时不知道a什么时候会写入。下面大家就和小编一起通过有名管道来演示进程间通信。管道创建之后它会在内存上分配一块空间也就是通过管道的数据存在了内存中而管道本身在磁盘里所以管道的大小永远为0。管道有两端大家可以想象一下它想一个水管有两头一端为读端一端为写端就像水管一遍流入一遍流出。即管道一个是读打开一个是写打开。让我们将下面的代码在终端中写入进行演示。//a.c #includestdio.h #includestdlib.h #includeunistd.h #includeassert.h #includefcntl.h #includestring.h int main(){ int fd open(fifo,O_WRONLY);//当前路径可以省略绝对路径要写全 assert(fd!-1); printf(fd %d\n,fd); write(fd,hello,5); close(fd); } //b.c #includestdio.h #includestdlib.h #includeunistd.h #includeassert.h #includefcntl.h int main(){ int fd open(fifo,O_RDONLY); assert(fd!-1); printf(fd %d\n,fd); char buf[128] {0}; read(fd,buf,127); printf(read:%s\n,buf); close(fd); exit(0); }//a.c #includestdio.h #includestdlib.h #includeunistd.h #includeassert.h #includefcntl.h #includestring.h int main(){ int fd open(fifo,O_WRONLY);//当前路径可以省略绝对路径要写全 assert(fd!-1); printf(fd %d\n,fd); while(1) { printf(input:\n); char buff[128] {0}; fgets(buff,128,stdin); if(strncmp(buff,end,3)0) { break; } write(fd,buff,strlen(buff)); } close(fd); } //b.c #includestdio.h #includestdlib.h #includeunistd.h #includeassert.h #includefcntl.h int main(){ int fd open(fifo,O_RDONLY); assert(fd!-1); printf(fd %d\n,fd); while(1){ char buf[128] {0}; if(read(fd,buf,127)0)//用于验证管道写端关闭读read返回值为0(第3个特点) { break; } printf(read:%s\n,buf); } close(fd); exit(0); }通过上面这两个个例子我们来总结一下管道的特点。1管道必须读写进程同时open否则会阻塞2如果管道没有数据那么read会阻塞3管道的写端关闭读read返回值为04管道打开的时候只有只读和只写两种方式读写方式打开是未定义的。二无名管道有名管道之所以不限制进程就是因为它有名字可以被找到而无名管道不可以如果不限制进程它又没有名字我们就没有办法找到它了。因此无名管道只能用于父子进程间通信。创建无名管道 pipe还是同样的思路学习一个新的命令要使用帮助手册 man pipe。//fi.c #includestdio.h #includestdlib.h #includeunistd.h #includeassert.h #includefcntl.h #includestring.h int main(){ int fd[2]; assert(pipe(fd)!-1); pid_t pid fork(); assert(pid!-1); //先open 后fork 共享文件描述符 if(pid0) { close(fd[1]); char buff[128] {0}; read(fd[0],buff,127); printf(child read:%s\n,buff); close(fd[0]); } else { close(fd[0]); write(fd[1],hello,5); close(fd[1]); } exit(0); }#includestdio.h #includestdlib.h #includeunistd.h #includeassert.h #includefcntl.h #includestring.h #includesignal.h void sig_fun(int sig){ printf(sig %d\n,sig); } int main(){ signal(SIGPIPE,sig_fun); int fd open(fifo,O_WRONLY);//当前路径可以省略绝对路径要写全 assert(fd!-1); printf(fd %d\n,fd); while(1) { printf(input:\n); char buff[128] {0}; fgets(buff,128,stdin); if(strncmp(buff,end,3)0) { break; } write(fd,buff,strlen(buff)); } //write(fd,hello,5); close(fd); }三管道的实现