当前位置: 首页 > news >正文

【Linux】进程间通信方式之管道

🤖个人主页:晚风相伴-CSDN博客

💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧

🙏如果内容有误的话,还望指出,谢谢!!!

✨下一篇文章:《进程间通信之共享内存》敬请期待💪

目录

理解进程间通信的本质

管道

管道的分类

匿名管道 

匿名管道如何实现进程间通信

 从文件描述符的角度理解匿名管道

用代码实现匿名管道

匿名管道读写的4个特殊情况 

管道的特点

利用匿名管道设计一个进程池

命名管道 

命名管道如何实现进程间通信 

命名管道的创建

代码实现命名管道 


理解进程间通信的本质

因为进程具有独立性,所以每个进程都只知道自己,而不知道有另外的进程存在,所以要实现不同进程间的通信,就要让不同的进程都能看到同一块资源,这块资源不属于任意一个进程,而是强调共享,利用这块资源就可以实现进程间通信了。

总结一下要点 

  1. 进程间通信的前提是要让不同的进程看到同一块资源
  2. 这一块资源不隶属于任何一个进程,而是被这些进程所共享

管道

管道想必大家都不陌生吧,在Linux命令行中我们可以通过管道( | )将一个进程输出连接到另一个进程的输入,从而实现数据的传输、连接、过滤和处理等功能。例如

管道也好理解就比如家里面的水管,一端进水,另一端出水。

管道的分类

  • 匿名管道
  • 命名管道 

🔥匿名管道 

匿名管道主要用于父子进程之间的通信。 

创建匿名管道的接口

 

参数:fildes是一个文件描述符数组,fildes[0]表示读端,fildes[1]表示写端

返回值:成功返回0,失败则返回-1并设置对应的错误码

🔥匿名管道如何实现进程间通信

  1. 父进程创建匿名管道,得到两个文件描述符,一个文件描述符用来读数据,另一个文件描述符用来写数据
  2. 调用fork创建子进程,创建出来的子进程会继承父进程创建管道时获得的那两个文件描述符
  3. 在父子进程中关闭不需要的文件描述符,比如子进程读取数据,父进程写入数据,那就在子进程中关闭写入的文件描述符,父进程中关闭读取的文件描述符,之后就可以进行相应的通信操作了。

 🔥从文件描述符的角度理解匿名管道

用代码实现匿名管道

#include <iostream>
#include <cstdio>
#include <cstring>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>using namespace std;int main()
{//1.创建管道int pipefd[2] = {0};//pipefd[0]:读端,pipefd[1]:写端int n = pipe(pipefd);assert(n != -1);//在Debug下才有用(void)n;//确保在release不报警告//条件编译
#ifdef DEBUGcout << "pipefd[0]:" << pipefd[0] << endl;cout << "pipefd[1]:" << pipefd[1] << endl;
#endif//2.创建子进程并构建通信信道——父进程写入,子进程读取pid_t id = fork();assert(id != -1);if(id == 0){//子进程close(pipefd[1]);//关闭子进程不需要的fd//读取数据char buffer[1024];while(true){//sleep(10);ssize_t s = read(pipefd[0], buffer, sizeof buffer - 1);if(s > 0){buffer[s] = 0;cout << "child get a massage [" << getpid() << "] father say:" << buffer << endl;}}close(pipefd[0]);exit(0);}//父进程close(pipefd[0]);//关闭父进程不需要的fd//发送数据string message = "我是父进程,我正在给你发送数据";int count = 0;//统计发送次数char send_buffer[1024];while(true){//sleep(10);//将要发送的数据打入send_massage中snprintf(send_buffer, sizeof send_buffer, "%s[%d] : %d\n", message.c_str(), getpid(), count++);//写入数据write(pipefd[1], send_buffer, strlen(send_buffer));sleep(1);}//等待子进程退出pid_t ret = waitpid(id, nullptr, 0);assert(ret);(void)ret;close(pipefd[1]);return 0;
}

 运行结果

🔥匿名管道读写的4个特殊情况 

情况一:写端很快,读端很慢,写端将缓冲区写满后就不能再写了,必须等读端读取后才能写让子进程读端sleep(10)秒钟

情况二:写端很慢,读端很快,管道中没有数据的时候,读端必须等待写端写入数据之后才能读

让父进程写端sleep(10)秒钟

情况三:写端关闭,读端读到0时表示读到了文件末尾

现象就是它会阻塞在那

情况四:读端关闭,写端继续写,当将缓冲区写满后操作系统会终止写进程

🔥管道的特点

  1. 管道是用于具有亲缘关系的进程之间进行进程间通信(常用于父子进程)
  2. 管道可以让父子进程之间进行协同,并且提供了访问控制(上面的4种情况就是访问控制的体现)
  3. 管道提供的是面向流式的通信服务(面向字节流)
  4. 管道的生命周期是随进程的
  5. 管道是单向通信的,也就是半双工通信的一种特殊情况

完整代码链接:匿名管道

利用匿名管道设计一个进程池

原理:fork多个子进程,然后用个随机数式的负载均衡让多个子进程都有概率能被使用到

 

匿名管道版进程池完整代码链接:匿名管道版进程池

🔥命名管道 

匿名管道的一个限制就是只能在具有亲缘关系的进程间通信,但是如果我们想在不相关的进程之间实现通信,那么就需要用到命名管道。

🔥命名管道如何实现进程间通信 

要实现进程间通信本质是要让不同的进程看到同一块资源。命名管道其实是在磁盘上创建了一个管道文件,这个管道文件可以随意被命名,并且有对应的属性但是没有内容,当我们在一个进程中打开这个管道文件并且将数据写入这个文件中,另一个进程也就可以打开这个管道文件并且从这个文件中读取数据,不同的进程都能打开并使用这个管道文件,所以也就让不同的进程看到了同一块资源。并且在这读写过程中管道文件中的数据不会加载到磁盘中,所以管道文件的大小始终为0保持不变。

命名管道的创建

在命令行上可以使用mkfifo命令来创建一个命名管道

也可以使用系统接口来创建命名管道

参数

  • pathname:命名管道文件的路径     
  • mode:管道文件的权限

返回值:成功返回0,失败则返回-1

代码实现命名管道 

comm.hpp 

#ifndef _COMM_H_
#define _COMM_H_#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "log.hpp"using namespace std;#define MODE 0666 // 文件权限
#define SIZE 128string ipcPath = "./myfifo.ipc"; // 管道文件路径#endif

server.cc

#include "comm.hpp"
#include <sys/wait.h>static void getMessage(int fd)
{// 进行通信操作char buffer[SIZE];while (true){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){// 读到文件结尾cerr << "[" << getpid() << "] "<< "read end of file, client quit, server quit too!" << endl;break;}else{// 读取失败perror("read");break;}}
}int main()
{// 创建管道文件if (mkfifo(ipcPath.c_str(), MODE) < 0){perror("mkfifo");exit(1);}logMessage(NORMAL, "创建管道文件成功, step 1"); // 打印日志// 打开管道文件int fd = open(ipcPath.c_str(), O_RDONLY);if (fd < 0){perror("open");exit(2);}logMessage(NORMAL, "打开管道文件成功, step 2");int nums = 5;for (int i = 0; i < nums; i++){pid_t id = fork();if (id == 0){// 子进程抢占式读取消息getMessage(fd);exit(1);}}// 等待子进程退出for (int i = 0; i < nums; i++){waitpid(-1, nullptr, 0);}// 关闭文件close(fd);logMessage(NORMAL, "关闭管道文件成功, step 3");// 通信完成,将管道文件删除unlink(ipcPath.c_str());logMessage(NORMAL, "删除管道文件成功, step 4");return 0;
}

client.cc 

#include "comm.hpp"int main()
{//获取管道文件int fd = open(ipcPath.c_str(), O_WRONLY);if(fd < 0){perror("open");exit(1);}//发送消息string buffer;while(true){cout << "Please Enter Message Line > ";getline(cin, buffer);write(fd, buffer.c_str(), buffer.size());}//关闭文件描述符close(fd);return 0;
}

完整代码链接:命名管道

相关文章:

【Linux】进程间通信方式之管道

&#x1f916;个人主页&#xff1a;晚风相伴-CSDN博客 &#x1f496;如果觉得内容对你有帮助的话&#xff0c;还请给博主一键三连&#xff08;点赞&#x1f49c;、收藏&#x1f9e1;、关注&#x1f49a;&#xff09;吧 &#x1f64f;如果内容有误的话&#xff0c;还望指出&…...

【Linux】yum与vim

文章目录 软件包管理器&#xff1a;yumLinux安装和卸载软件包Linux中的编辑器&#xff1a;vimvim下的底行模式vim下的正常模式vim下的替换模式vim下的视图模式vim下的多线程 软件包管理器&#xff1a;yum yum其实就是一个软件,也可以叫商店 和你手机上的应用商店或app store一…...

苍穹外卖Day06笔记

疯玩了一个月&#xff0c;效率好低&#xff0c;今天开始捡起来苍穹外卖~ 1. 为什么不需要单独引入HttpClient的dependency&#xff1f; 因为我们在sky-common的pom.xml中已经引入了aliyun-sdk-oss的依赖&#xff0c;而这个依赖低层就引入了httpclinet的依赖&#xff0c;根据依…...

Maximo 使用 REST API 创建 Cron Task

接前面几篇文章&#xff0c;我没有了 automation script 以后&#xff0c;有时候需要让其定期自动执行&#xff0c;这时候就可以通过 Cron Task 来实现了。 通过Maximo REST API 来创建 Cron Task request&#xff1a; POST {{base_url}}/api/os/mxapicrontaskdef?apikey{{…...

【镜像仿真篇】磁盘镜像仿真常见错误

【镜像仿真篇】磁盘镜像仿真常见错误 记系统镜像仿真常见错误集—【蘇小沐】 1、实验环境 2023AFS39.E01&#xff08;Windows11系统镜像&#xff09;Arsenal Image Mounter&#xff0c;[v3.10.262]‍Vmware Workstation 17 Pro&#xff0c;[v17.5.1]Windows 11 专业工作站版…...

代码随想录算法训练营DAY45|C++动态规划Part7|70.爬楼梯(进阶版)、322. 零钱兑换、279.完全平方数

文章目录 70.爬楼梯&#xff08;进阶版&#xff09;⭐️322. 零钱兑换思路CPP代码总结 279.完全平方数思路CPP代码 70.爬楼梯&#xff08;进阶版&#xff09; 卡码网&#xff1a;57. 爬楼梯 文章讲解&#xff1a;70.爬楼梯(进阶版) 本题就是典型了完全背包排列问题&#xff0c;…...

Linux(openEuler、CentOS8)企业内网DHCP服务器搭建(固定Mac获取指定IP)

----本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文&#xff09;---- 目录 一、知识点二、实验&#xff08;一&#xff09;为服务器配置网卡和IP&#xff08;二&#xff09;为服务器安装DHCP服务软件&#xff08;三&a…...

c#读取hex文件方法,相对来说比较清楚

Hex文件解读_c#读取hex文件-CSDN博客 https://wenku.csdn.net/answer/d67f30cf834c435ca37c3d1ef5e78a62?ops_request_misc%257B%2522request%255Fid%2522%253A%2522171498156816800227423661%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&…...

【ytb数据采集器】按关键词批量爬取视频数据,界面软件更适合文科生!

一、背景介绍 1.1 爬取目标 用Python独立开发的爬虫工具&#xff0c;作用是&#xff1a;通过搜索关键词采集油管的搜索结果&#xff0c;包含14个关键字段&#xff1a;关键词,页码,视频标题,视频id,视频链接,发布时间,视频时长,频道名称,频道id,频道链接,播放数,点赞数,评论数…...

三条命令快速配置Hugging Face

大家好啊&#xff0c;我是董董灿。 本文给出一个配置Hugging Face的方法&#xff0c;让你在国内可快速从Hugging Face上下在模型和各种文件。 1. 什么是 Hugging Face Hugging Face 本身是一家科技公司&#xff0c;专注于自然语言处理&#xff08;NLP&#xff09;和机器学习…...

Python网络编程 03 实验:FTP详解

文章目录 一、小实验FTP程序需求二、项目文件架构三、服务端1、conf/settings.py2、conf/accounts.cgf3、conf/STATUS_CODE.py4、启动文件 bin/ftp_server.py5、core/main.py6、core/server.py 四、客户端1、conf/STATUS_CODE.py2、bin/ftp_client.py 五、在终端操作示例 一、小…...

个人银行账户管理程序(2)

在&#xff08;1&#xff09;的基础上进行改进 1&#xff1a;增加一个静态成员函数total&#xff0c;记录账户总金额和静态成员函数getTotal 2对不需要改变的对象进行const修饰 3多文件实现 account。h文件 #ifndef _ACCOUNT_ #define _ACCOUNT_ class SavingAccount {pri…...

2024.04.19校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招&转正实习 | 美团无人机业务部招聘&#xff08;内推&#xff09; 校招&转正实习 | 美团无人机业务部招聘&#xff08;内推&#xff09; 2、校招&实习 | 快手 这些岗位…...

Python并发编程 04 进程与线程基础

文章目录 一、操作系统简介二、进程三、线程四、线程的调用1、示例2、join方法3、setDaemon方法4、继承式调用&#xff08;不推荐&#xff09;5、其他方法 一、操作系统简介 ①操作系统是一个用来协调、管理和控制计算机硬件和软件资源的系统程序&#xff0c;它位于硬件和应用…...

模板引擎Freemarker

什么是模板引擎 根据前边的数据模型分析&#xff0c;课程预览就是把课程的相关信息进行整合&#xff0c;在课程预览界面进行展示&#xff0c;课程预览界面与课程发布的课程详情界面一致。 项目采用模板引擎技术实现课程预览界面。什么是模板引擎&#xff1f; 早期我们采用的…...

刷题训练之模拟

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;熟练掌握模拟算法。 > 毒鸡汤&#xff1a;学习&#xff0c;学习&#xff0c;再学习 ! 学&#xff0c;然后知不足。 > 专栏选自&#xff1a;刷题训…...

视频监控平台:交通运输标准JTT808设备SDK接入源代码函数分享

目录 一、JT/T 808标准简介 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;协议特点 1、通信方式 2、鉴权机制 3、消息分类 &#xff08;三&#xff09;协议主要内容 1、位置信息 2、报警信息 3、车辆控制 4、数据转发 二、代码和解释 &#xff08;一…...

【C++】多态 — 多态的细节补充(下篇)

前言&#xff1a; 我们学习了多态的形式和如何使用多态&#xff0c;这一章我们将来讲一讲多态的原理… 目录 动态绑定与静态绑定: 动态绑定与静态绑定: 静态绑定又称为前期绑定(早绑定)&#xff0c;在程序编译期间确定了程序的行为&#xff0c;也称为静态多态&#xff0c;比如…...

系统安全与应用【2】

1.开关机安全控制 1.1 GRUB限制 限制更改GRUB引导参数 通常情况下在系统开机进入GRUB菜单时&#xff0c;按e键可以查看并修改GRUB引导参数&#xff0c;这对服务器是一个极大的威胁。可以为GRUB 菜单设置一个密码&#xff0c;只有提供正确的密码才被允许修改引导参数。 实例&…...

EtherCAT总线速度轴控制功能块(COSESYS ST源代码)

测试环境为汇川PLC,型号 AM402-CPU1608TP、伺服驱动器为禾川X3E,具体通信配置可以参考下面文章链接: 1、使能和点动控制 汇川AM400PLC通过EtherCAT总线控制禾川X3E伺服使能和点动控制-CSDN博客文章浏览阅读31次。进行通信之前需要安装禾川X3E的XML文件,具体方法如下:1、汇…...

【码银送书第十九期】《图算法:行业应用与实践》

作者&#xff1a;嬴图团队 01 前言 在当今工业领域&#xff0c;图思维方式与图数据技术的应用日益广泛&#xff0c;成为图数据探索、挖掘与应用的坚实基础。本文旨在分享嬴图团队在算法实践应用中的宝贵经验与深刻思考&#xff0c;不仅促进业界爱好者之间的交流&#xff0c;…...

无监督式学习

1.是什么&#xff1f; 无监督式学习与监督式学习**最大的区别就是&#xff1a;**没有事先给定的训练实例&#xff0c;它是自动对输入的示例进行分类或者分群&#xff1b; 优点&#xff1a;不需要标签数据&#xff0c;极大程度上扩大了我们的数据样本&#xff0c;其次不受监督信…...

docker 安装镜像及使用命令

目录 1. Mysql2. Redis3. Nginx4. Elasticsearch官网指导 docker pull 容器名:版本号 拉取容器, 不指定版本号默认最新的 run 运行 -d 后台运行 -p 3306:3306 -p是port 对外端口:对内端口 –name xyy_mysql 容器名称 -e MYSQL_ROOT_PASSWORD123456 环境变量 -v 系统地址:docker…...

Python运维之多进程!!

本节的快速导航目录如下喔&#xff01;&#xff01;&#xff01; 一、创建进程的类Process 二、进程并发控制之Semaphore 三、进程同步之Lock 四、进程同步之Event 五、进程优先队列Queue 六、多进程之进程池Pool 七、多进程之数据交换Pipe 一、创建进程的类Process mu…...

Redis(无中心化集群搭建)

文章目录 1.无中心化集群1.基本介绍2.集群说明 2.基本环境搭建1.部署规划&#xff08;6台服务器&#xff09;2.首先删除上次的rdb和aof文件&#xff08;对之前的三台服务器都操作&#xff09;1.首先分别登录命令行&#xff0c;关闭redis2.清除/root/下的rdb和aof文件3.把上次的…...

基于springboot+jsp+Mysql的商务安全邮箱邮件收发

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

三.Django--ORM(操作数据库)

目录 1 什么是ORM 1.1 ORM优势 1.2ORM 劣势 1.3 ORM与数据库的关系 2 ORM 2.1 作用 2.2 连接数据库 2.3 表操作--设置字段 2.4 数据库的迁移 写路由增删改查操作 项目里的urls.py: app里的views.py: 注意点: 1 什么是ORM ORM中文---对象-关系映射 在MTV,MVC设计…...

【华为】AC直连二层组网隧道转发实验配置

【华为】AC直连二层组网隧道转发实验配置 实验需求拓扑配置AC数据规划表 AC的配置顺序AC1基本配置(二层通信)AP上线VAP组关联--WLAN业务流量 LSW1AR1STA获取AP的业务流量 配置文档 实验需求 AC组网方式&#xff1a;直连二层组网。 业务数据转发方式&#xff1a;隧道转发。 DHC…...

第 129 场 LeetCode 双周赛题解

A 构造相同颜色的正方形 枚举&#xff1a;枚举每个 3 3 3\times 3 33的矩阵&#xff0c;判断是否满足条件 class Solution {public:bool canMakeSquare(vector<vector<char>>& grid) {for (int i 0; i < 2; i)for (int j 0; j < 2; j) {int c1 0, c…...

GStreamer日志调试笔记

1、查询所有分类 #gst-launch-1.0 --gst-debug-help 2、查询videotestsrc的日志 #gst-launch-1.0 --gst-debug-help | findstr videotestsrc 结果&#xff1a; 3、使用--gst-debug设置相应日志类型的相应等级&#xff0c;越大显示日志越多&#xff0c;排查内存泄露可以设置为9 …...

这几年做哪个网站致富/互联网平台推广是什么意思

//学习继承Descriptionauthor huoyudate 2020年2月10日下午9:34:01param args一、继承性的好处减少了代码的冗余&#xff0c;提高了代码的复用性便于功能的扩展为之后多态的使用提供了前提二、继承的格式 class A extends B{}A:子类、派生类 subclassB&#xff1a;父类、起类、…...

外贸网站怎么做会吸引眼球/河北网站推广公司

第三章 哈希算法 哈希算法又称散列函数算法&#xff0c;是一种查找算法。简单来说&#xff0c;就是把一些复杂的数据&#xff0c;通过某种函数映射关系&#xff0c;映射成更加容易查找的方式。但是这种映射关系有可能会发生多个关键字映射到同一地址的现象&#xff0c;我们称之…...

装修公司网站开发/中国营销网

C操作符的优先级 C操作符的优先级 操作符及其结合性 功能 用法 L L L:: :: ::全局作用域 类作用域 名字空间作用域::name class::name namespace::nameL L L L L. -> [] () ()成员选择 成员选择 下标 函数调用 类型构造object.member pointer->member variable[exp…...

免费网站建设市场/怎么做推广让别人主动加我

计算机二级access题库答案在文末1&#xff0e;在Access数据库中&#xff0c;一个关系就是一个【 A】。A)二维表 B)记录C)字段 D)数据库 综合数据2. 设有部门和员工两个实体&#xff0c;每个员工只能属于一个部门&#xff0c;一个部门可以有多名员工&#xff0c;则部门与…...

哈尔滨网站制作哪儿好薇/广告推广平台

升序排列的整数数组 nums 在预先未知的某个点上进行了旋转&#xff08;例如&#xff0c; [0,1,2,4,5,6,7] 经旋转后可能变为 [4,5,6,7,0,1,2] &#xff09;。 请你在数组中搜索 target &#xff0c;如果数组中存在这个目标值&#xff0c;则返回它的索引&#xff0c;否则返回 -…...

专业做家具的网站/如何做网站优化seo

Word是我们常用的的办公软件&#xff0c;广泛被运用&#xff0c;那么我们怎么把Word转换为网页html格式&#xff1f; 文件&#xff1a;url80.ctfile.com/f/25127180-734987515-e5f15e?p551685 (访问密码: 551685) 需要软件&#xff1a; word2003 或 wps 个人建议用wps更方便…...