进程通信——匿名管道实现和验证
来源:互联网 发布:gommdb数据库编辑器 编辑:程序博客网 时间:2024/06/04 18:34
今天我们来分享一下,Linux中关于进程通行中最简单的匿名管道的实现和相关性质的验证。
进程通信的原理是:多个进程看到同一份公共资源(文件),能对该资源进行相应操作,不同进程间即可进行通信。一般有操作系统(内核)提供这一公共资源。今天我们利用匿名管道来实现进程通信。
首先介绍一下,匿名管道的特点:
1.匿名管道只能实现单向通信。
2.匿名管道只能实现有血缘关系的进程之间的通信。
3.管道是一个随进程的文件,即当进程退出时,管道文件不存在。
4.管道的数据通信是基于数或者字节流的通信。
5.管道内部实现同步互斥,满足安全性,保证数据的一致性。
接着,举例父子进程的通信来说明匿名管道的通信过程。
A.利用pipe函数建立匿名管道,得到管道的读写文件描述符。
B.fork创建子进程。由于管道的读写文件描述符属于数据,子进程会依照父进程复制一份,即父子同时拥有指向管道文件的读写文件描述符,用有一份公共的管道文件,就拥有了进程通行的条件。
C.由于匿名管道只能实现进程间的单项通信,所以需要手动关闭父子进程冗余的读写端(读写文件描述符)。
注:子写父读,关闭子进程的读端和父进程的写端。需求不同则反之。
D.父子进程进行相应的读写,实现进程通信。
图解如下:
我们需要验证以下四种情况:
A.读端不关闭,且不读取管道内容,写端不断向管道写内容,当管道被写满,写端只能阻塞式等待。
部分代码截图和运行结果如下:
B.写端不关闭,且不向管道写内容,读端不断读取管道内容,当管道中数据读完,读端只能阻塞式等待。
部分代码截图和运行结果如下:
C.读端先于写端关闭,写端收到异常信号退出。
部分代码截图和运行结果如下:
D.写端先于读端关闭,当读到0时,即读到文件结尾,退出。
部分代码截图和运行结果如下:
实现进程通信——匿名管道,代码如下:
#include<stdio.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<stdlib.h>#include<unistd.h>#include<string.h> int main() { umask(0); int pfd[2]; if(pipe(pfd) < 0){ perror("pipe wrong!\n"); exit(1); } pid_t id = fork(); if(id<0){ perror("wrong!\n"); exit(1); } if(id == 0){//child close(pfd[0]); int i = 0; char* tmp = "hello !"; // while(1){ // i++; // if(i < 5){ // printf("child: %s, num: %d\n", tmp, i); // write(pfd[1], tmp, strlen(tmp)); // } // else//i>=5 // { // exit(1); // } // sleep(1); // } // exit(1); while(1){ printf("child: %s, num: %d \n", tmp, i); i++; if(i>10)return 0; write(pfd[1], tmp, strlen(tmp)); } } else{//parent int status; close(pfd[1]); char tmp[1024]; int i=0; while(1){ ssize_t s = read(pfd[0], tmp, sizeof(tmp)-1); // if(i>5) close(pfd[0]); // i++; if(s>0){ tmp[s] = 0; printf("parent:%s\n", tmp); } else if(s == 0){//child quit,so parent will quit printf("child quit,so parent will quit!\n"); sleep(5); break; } // else{//wrong // printf("read wrong!\n"); // int status; // pid_t s = waitpid(id, &status, 0); // if(s>0){ // printf("waitpid success! sig:%d, exitCode: %d\n",\ // WIFEXITED(status),WEXITSTATUS(status) ); // } // exit(2); // } } if(waitpid(id, &status, 0)>0){ printf("waitpid success! sig:%d, exitCode: %d\n",\ WIFEXITED(status),WEXITSTATUS(status) ); } } return 0; }
分享如上,欢迎斧正!
注:代码虽乱但全。若有错误和遗漏,请参见代码截图或评论!
- 进程通信——匿名管道实现和验证
- 进程间通信——匿名管道
- 进程间通信——匿名管道
- Windows进程通信——匿名管道
- 进程间通信—‘匿名管道’
- 进程间通信—匿名管道
- 进程通信:匿名管道和命名管道
- 通过匿名管道实现进程间通信
- 进程间通信 - 匿名管道实现
- 进程间通信详解 - 匿名管道实现
- 通过匿名管道实现进程间通信
- 进程间通信详解 - 匿名管道实现
- 进程间通信 - 匿名管道实现
- 进程间通信 - 匿名管道实现
- 进程间通信 - 匿名管道实现
- 通过匿名管道实现进程间通信
- 进程间通信 - 匿名管道实现
- 进程间通信 - 匿名管道实现
- redis 空格问题
- 初学欧拉图,知识总结,后续增加
- c# enum
- 从零认识tomcat,构建一机多实例tomcat集群
- hdu1172猜数字
- 进程通信——匿名管道实现和验证
- 异或交换数值
- springmvc+mybatis+oracle简单登录
- 题目:初识python,第一个python程序,交互式环境下的输出以及文本编辑器介绍
- _crol_和_cror_的使用
- 学JS必看-JavaScript数据结构深度剖析
- struts2 Action (2)
- Zookeeper开发常见问题
- psql 列转行