一、进程间通信
1、进程间通信的目的
- 数据传输:一个进程需要把他的数据传给另外一个进程。
- 资源共享:多个进程之间共享同样的资源。
- 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
2、进程间通信发展
- 管道(本质上就是文件)
- System V进程间通信
- POSIX进程间通信
3、进程间通信分类
管道
- 匿名管道pipe
- 命名管道
System V IPC
- System V 消息队列
- System V 共享内存
- System V 信号量
POSIX IPC
- 消息列队
- 共享内存
- 信号量
- 互斥量
- 条件变量
- 读写锁
二、管道
1、什么是管道?
管道是Unix中最古老的进程间通信的形式。
我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”
2、用fork来共享管道原理
文章来源:https://www.toymoban.com/news/detail-845215.html
3、站在文件描述符角度-深度理解管道
文章来源地址https://www.toymoban.com/news/detail-845215.html
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>
using namespace std;
#define NUM 1024
#define N 2
void Writer(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));
}
}
void Reader(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;
}
}
}
int main()
{
int pipefd[N]={0};
int n=pipe(pipefd);
if(n<0) return 1;
pid_t id=fork();
if(id<0) return 2;
if(id==0)
{
//子进程
close(pipefd[0]);
Writer(pipefd[1]);
exit(0);
}
//父进程
close(pipefd[1]);
Reader(pipefd[0]);
pid_t rid=waitpid(id,nullptr,0);
return 0;
}
到了这里,关于Linux——进程间通信&&管道的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!