【linux进程间通信(1)】匿名管道和命名管道

news/2025/1/10 13:17:27/

目录

  • 前言
  • 1. 进程间通信的方法
  • 2. 管道的简单介绍
  • 3. 匿名管道
  • 4. 命名管道
  • 5. 总结

前言

众所周知,进程运行是具有独立性的,想要进程间进行通信就要打破这种独立性,而进程间通信的本质其实是让不同的进程看见同一份资源!

本章重点:

本篇文章会介绍进程间通信中常见的几种方式,并且着重讲解匿名管道和命名管道的这两种通信手段的原理和代码的实现.

1. 进程间通信的方法

首先通信种类分为三大类:

  • 管道
  • system V
  • POSIX
    在这里插入图片描述
    当然网络通信的本质其实也是进程间的通信,但是本篇文章的重点是利用管道通信!!!

2. 管道的简单介绍

首先要回答什么是管道,在学习Linux指令时我们使用过竖划线 | 也就是管道,把从一个进程连接到另一个进程的数据流称为“管道”

在这里插入图片描述

在管道通信中,管道的本质其实就是一个被系统打开的文件,然而用管道进行通信的本质就是让不同的进程看见相同的资源(文件).

3. 匿名管道

匿名管道的原理:
在这里插入图片描述


在这里插入图片描述

匿名管道的使用:
在这里插入图片描述

piped的底层就是open,参数是输出型参数,
不需要路径和文件名,所以叫做匿名管道.

对于匿名管道来说,通常用于父子,进程之间的通信,在父进程使用pipe创建好管道后,再使用fork创建子进程,此时子进程会将父进程的文件描述符表给拷贝过来,也就天然的拥有这两个管道文件了!
在这里插入图片描述

并且此时我们会面临两个问题:
1. 读取方将文件关闭了会发送什么?
2. 读取方在文件中没有数据时会干什么?

  • 读端关闭后,写端进程会终止
  • 当管道无数据时读端会阻塞

有了上面的经验后,现在可以编码验证一下:

int main()
{//创建管道int pipefd[2]={0}; //0下标表示读取端,1下标表示写入端int n = pipe(pipefd);assert(n!=-1);(void)n;
#ifdef DEBUG//条件编译cout<<"[0]: "<<pipefd[0]<<" "<<"[1]: "<<pipefd[1]<<endl;
#endif//创建子进程pid_t id = fork();assert(id!=-1);if(id==0)//子进程, 构建单向通信{close(pipefd[1]);char buffer[1024];while(1){ssize_t s = read(pipefd[0],buffer,sizeof(buffer)-1);if(s>0){buffer[s]=0;cout<<"father# "<<buffer<<endl;}else//read的返回值等于0代表父进程的管道文件已经close了{cout<<"写入结束,子进程退出";break;}}exit(0);}//父进程写入,子进程读取close(pipefd[0]);string str = "我在给子进程发信息";int count=0;char send_buffer[1024];while(count<=5){//构建一个变化的字符串snprintf(send_buffer, sizeof(send_buffer),"%s[%d]: %d",str.c_str(),getpid(),count++);//往缓冲区里写入数据//写入到管道中write(pipefd[1],send_buffer,sizeof(send_buffer));sleep(1);}close(pipefd[1]);pid_t ret = waitpid(id,NULL,0);assert(ret > 0);return 0;
}

总结管道的4种情况,5种特征:
在这里插入图片描述

4. 命名管道

匿名管道的一个限制就是必须是在有血缘关系的进程间才能通信,使用命名管道可以解决这个问题.

在这里插入图片描述

匿名管道和命名管道的区别:

  • 匿名管道由pipe函数创建并打开。
  • 命名管道由mkfifo函数创建,打开用open.
  • FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

命名管道的打开规则:
在这里插入图片描述

命名管道简单通信的代码实现:
读端代码:

#define SIZE 1024
#define MODE 0666
string ipcpath = "./fifo.ipc";
static void getmessage(int fd)
{//编写通信代码char buffer[SIZE];while(1){memset(buffer,'\0',sizeof(buffer));ssize_t s = read(fd,buffer,sizeof(buffer)-1);if(s>0)//读取成功{cout<<"["<<getpid()<<"] "<<"client say: "<<buffer<<endl;}else if(s==0)//写端关闭,并且读到end{cerr<<"["<<getpid()<<"]"<<"read end"<<endl;break;}else//读取失败{perror("read");break;}}
}
int main()
{//创建管道文件int n = mkfifo(ipcpath.c_str(),MODE);if(n<0){perror("mkfifo");exit(1);}//文件操作int fd = open(ipcpath.c_str(),O_RDONLY);//这里必须等待client进程将此管道文件打开后才能执行下面的代码if(fd<0){perror("open");exit(2);}for(int i=0;i<4;i++){int id = fork();if(id==0){getmessage(fd);exit(0);}}close(fd);return 0;
}

写端代码:

#define SIZE 1024
#define MODE 0666
string ipcpath = "./fifo.ipc";
int main()
{//client不用自己创建管道文件,只需获取文件即可int fd = open(ipcpath.c_str(),O_WRONLY);if(fd<0){perror("open");exit(1);}//通信过程string buffer;while(1){cout<<"please Enter message: ";getline(cin,buffer);write(fd,buffer.c_str(),buffer.size());}close(fd);return 0;
}

5. 总结

虽然匿名管道和命名管道已经包含了对于有血缘关系和无血缘关系的进程的通信,但是毕竟调用read和write这些系统调用接口会不断的在用户态和内核态进行切换,比较消耗资源,所以管道不是最好的!


http://www.ppmy.cn/news/1561983.html

相关文章

Kubernetes Gateway API-4-TCPRoute和GRPCRoute

1 TCPRoute 目前 TCP routing 还处于实验阶段。 Gateway API 被设计为与多个协议一起工作&#xff0c;TCPRoute 就是这样一个允许管理TCP流量的路由。 在这个例子中&#xff0c;我们有一个 Gateway 资源和两个 TCPRoute 资源&#xff0c;它们按照以下规则分配流量&#xff1…

Node.js——path(路径操作)模块

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

高级java每日一道面试题-2025年01月04日-并发篇-说说CyclicBarrier和CountDownLatch的区别?

如果有遗漏,评论区告诉我进行补充 面试官: 说说CyclicBarrier和CountDownLatch的区别? 我回答: 在Java高级面试中&#xff0c;CyclicBarrier和CountDownLatch是两个经常被提及的并发工具类&#xff0c;它们都用于实现线程间的同步&#xff0c;但存在显著的区别。以下是对这…

深度学习中的卷积和反卷积(二)——反卷积的介绍

1 简介 反卷积&#xff08;deconvolution&#xff09;又称转置卷积&#xff0c;是卷积的拟操作&#xff0c;常用于GAN等模型中。反卷积是上采样的一种&#xff0c;上采样是指将特征图维度恢复到原始图的维度&#xff0c;这种增大维度的过程被称为上采样。上采样可以用插值或反…

linux音视频采集技术: v4l2

简介 在 Linux 系统中&#xff0c;视频设备的支持和管理离不开 V4L2&#xff08;Video for Linux 2&#xff09;。作为 Linux 内核的一部分&#xff0c;V4L2 提供了一套统一的接口&#xff0c;允许开发者与视频设备&#xff08;如摄像头、视频采集卡等&#xff09;进行交互。无…

毕业项目推荐:基于yolov8/yolov5/yolo11的动物检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…

JetBrains IDEs和Visual Studio Code的对比

JetBrains IDEs和Visual Studio Code的对比 JetBrains IDEs是捷克JetBrains公司开发的一系列集成开发环境(IDE)。以下是具体介绍:IntelliJ IDEA是JetBrains 公司的一款产品 主要产品 IntelliJ IDEA:一款功能强大且广泛应用的Java集成开发环境,有开源免费的社区版和商业收…

linux 使用 MySQL Performance Schema 和 Prometheus + Grafana 来监控 MySQL 性能

&#x1f3af; 方案 1&#xff1a;使用 MySQL Performance Schema Performance Schema 是 MySQL 内置的性能监控工具&#xff0c;适合排查慢查询、锁等待、资源使用等问题。 ✅ 步骤 1&#xff1a;启用 Performance Schema 1️⃣ 在 MySQL 配置文件中&#xff08;通常是 /et…