Linux进程间通信——管道
管道
- 什么是管道?一个进程连接到另一个进程的一个数据流称为一个“管道” 。
- 用于父子间的通信
- 管道最大64K , 由环形队列组成
- 需要占用两个文件描述符 , 分别作为管道读端、写端
- 管道是半双工的 , 需要确定通信方向父写子读 , 关闭父读、子写子写父读 , 关闭子读、父写
- 优点:稳定、经典
int pipe(int file_descriptor[2]);
功 能:创建一无名管道参 数:file_descriptor:文件描述符数组,其中file_descriptor[0]表示读端,file_descriptor[1]表示写端返回值:成功返回0 , 失败返回-1
开辟了管道之后如何实现两个进程间的通信呢?比如可以按下面的步骤通信 。
文章插图
1、父进程调用pipe开辟管道 , 得到两个文件描述符指向管道的两端 。 2、父进程调用fork创建子进程 , 那么子进程也有两个文件描述符指向同一管道 。 3、父进程关闭管道读端 , 子进程关闭管道写端 。 父进程可以往管道里写 , 子进程可以从4、管道里读 , 管道是用环形队列实现的 , 数据从写端流入从读端流出 , 这样就实现了进程间通信 。
#include #include #define MAXLINE 80int main(void){ int n; int fd[2]; pid_t pid; char line[MAXLINE]; if (pipe(fd) < 0){perror("pipe");exit(1); } if ((pid = fork()) < 0){perror("fork");exit(1); } if (pid > 0) // 父进程{close(fd[0]);//关闭读端write(fd[1], "hello world\n", 12);wait(NULL); } else//子进程 {close(fd[1]);//关闭写端n = read(fd[0], line, MAXLINE);write(STDOUT_FILENO, line, n); } return 0;}
运行结果文章插图
注意事项
- 如果试图从管道写端读取数据 , 或者向管道读端写入数据都将导致错误发生
- 写端未写完 , 写端暂时无数据 , 读端再次去读 , read发生阻塞(读太快)
- 读端未读完 , 写端满了 , 写端再次写 , write发生阻塞(写太快)
- 读端关闭 , 写端写数据 , 产生SIGPIPE信号 , 默认会终止进程
- 写端关闭 , 当数据读完 , 再次读返回0
文章插图
文章插图
有名管道fifopipe是有血缘关系进程之间的通信 , 那么当没有血缘关系的进程想要通信怎么办?
- 创建一个有名管道fifo(也叫做named pipe) , 解决无血缘关系的进程通信
- fifo是一个设备文件 , 本身无大小 , 在文件系统中以文件名的形式存在 , 因此即使进程与创建fifo的进程不存在血缘关系也依然可以通信 , 前提是可以访问该路径 。
- fifo总是遵循先进先出的原则 , 即第一个进来的数据会第一个被读走
文章插图
与匿名管道pipe的区别
- 提供了一个路径名与之关联 , 以fifo文件的形式存储于文件系统中 , 能够实现任何两个进程之间通信 。 而匿名管道对于文件系统是不可见的 , 它仅限于在父子进程之间的通信 。但是fifo底层是由pipe实现的 。
- 命令行上创建
- 程序内创建头文件:#include #include 函数原型:int mkfifo(const char *pathname, mode_t mode);
#include #include #include #include #include #include #include int main(int argc, char* argv[]){ int fd; char buff[1024] = "hello world\n"; if (argc < 2) {printf("enter you fifoname\n");exit(1); } fd = open(argv[1], O_WRONLY);//只写方式打开 if (fd < 0) {perror("open\n"); } write(fd, buff, strlen(buff));//写入hello world close(fd); return 0;}
读进程#include #include #include #include #include #include #include int main(int argc, char* argv[]){ int fd; int len; char buff[1024] = "hello world\n"; if (argc < 2) {printf("enter you fifoname\n");exit(1); } fd = open(argv[1], O_RDONLY);//只写方式打开 if (fd < 0) {perror("open\n"); } len = read(fd, buff, sizeof(buff)); write(STDOUT_FILENO, buff, len); close(fd); return 0;}
【Linux进程间通信——管道】测试结果如下文章插图
首先myfifo是我们提前创建好的fifo管道文件 , 然后执行写进程 , 再执行读进程 。 读到了hello world , 执行前后myfifo文件大小都为0
- 星期一|亚马逊:黑五与网络星期一期间 第三方卖家销售额达到48亿美元
- 空间|垃圾文件正在吞噬你的C盘空间用这四种方法,还你一个干净的C盘
- 广告点击|广告效果评估:30天的广告时间评估最全面
- 要来|折叠屏iPhone终于要来了!可惜发布的时间有点晚,你愿意等吗?
- 智能手机品|越南手机悄然崛起!创立短短2年时间,在当地接连击退苹果、小米
- 科技|短视频行业领先 云想科技成长空间广阔
- 黑色|亚马逊黑色星期五及网购星期一期间全球第三方卖家销售额超48亿美元
- 移植|开发者将移植ARM Mac的Linux系统 但需要得到资金支持
- 网间|新外观专利陆续曝光 徐起和网间透露realme极致性能新机将至
- Android|索尼Android 11更新时间表公布 最早本月开始