**📘北尘_**:个人主页
🌎个人专栏:《Linux操作系统》《经典算法试题 》《C++》 《数据结构与算法》
☀️走在路上,不忘来时的初心
文章目录
一、进程间通信
1、进程间通信的目的
- 数据传输:一个进程需要把他的数据传给另外一个进程。
- 资源共享:多个进程之间共享同样的资源。
- 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
2、进程间通信发展
- 管道(本质上就是文件)
- System V进程间通信
- POSIX进程间通信
3、进程间通信分类
管道
- 匿名管道pipe
- 命名管道
System V IPC
- System V 消息队列
- System V 共享内存
- System V 信号量
POSIX IPC
- 消息列队
- 共享内存
- 信号量
- 互斥量
- 条件变量
- 读写锁
二、管道
1、什么是管道?
管道是Unix中最古老的进程间通信的形式。
我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”
2、用fork来共享管道原理
3、站在文件描述符角度-深度理解管道
4、管道的五个特点
- 具有血缘关系才可以进程间通信。
- 管道只能进程单向通信。
- 父子协同 同步和互斥。
- 面向字节流。
- 管道是基于文件的,而文件的声明周期是随进程的。
5、管道的四种场景
- 读写端正常,如果管道为空,写端会堵塞
- 读写端正常,如果管道已满,读端会堵塞
- 读端正常读,写端关闭,读端就会读到0,表示读到文件结尾,不会堵塞
- 写端正常读,读端关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出。
6、代码示例
#include<iostream>#include<sys/types.h>#include<cstdio>#include<unistd.h>#include<sys/wait.h>#include<string>#include<cstring>usingnamespace std;#defineNUM1024#defineN2voidWriter(int fd){char buffer[NUM];
string s="hello l am child";
pid_t id=getpid();int number=0;while(1){sleep(1);
buffer[0]=0;snprintf(buffer,sizeof(buffer),"%s-%d-%d",s.c_str(),id,number++);write(fd,buffer,strlen(buffer));}}voidReader(int id){char buffer[NUM];while(1){
buffer[0]=0;
ssize_t n=read(id,buffer,sizeof(buffer));if(n>0){
buffer[n]='\0';
cout<<buffer<<endl;}}}intmain(){int pipefd[N]={0};int n=pipe(pipefd);if(n<0)return1;
pid_t id=fork();if(id<0)return2;if(id==0){//子进程close(pipefd[0]);Writer(pipefd[1]);exit(0);}//父进程close(pipefd[1]);Reader(pipefd[0]);
pid_t rid=waitpid(id,nullptr,0);return0;}
版权归原作者 北尘_ 所有, 如有侵权,请联系我们删除。