【linux进程间通信(一)】匿名管道和命名管道
💓博主CSDN主页:杭电码农-NEO💓
⏩专栏分类:Linux从入门到精通⏪
🚚代码仓库:NEO的学习日记🚚
🌹关注我🫵带你学更多操作系统知识
🔝🔝
进程间通信
- 1. 前言
- 2. 进程间通信的方法
- 3. 管道的简单介绍
- 4. 匿名管道
- 5. 命名管道
- 6. 总结以及拓展
1. 前言
众所周知,进程运行是具有独立性的,
想要进程间进行通信就要打破这种
独立性,而进程间通信的本质其实是
让不同的进程看见同一份资源!
本章重点:
本篇文章会介绍进程间通信中常见
的几种方式,并且着重讲解匿名管道
和命名管道的这两种通信手段的原理
和代码的实现.
2. 进程间通信的方法
首先通信种类分为三大类:
管道
system V
POSIX
当然网络通信的本质其实也是进程
间的通信,但是本篇文章的重点是
利用管道通信!!!
3. 管道的简单介绍
首先要回答什么是管道,在学习
Linux指令时我们使用过竖划线 |
也就是管道,把从一个进程连接
到另一个进程的数据流称为“管道”
在管道通信中,管道的本质其实就是
一个被系统打开的文件,然而用管道
进行通信的本质就是让不同的进程
看见相同的资源(文件)
并且管道是单向通信的
,即一个进程
不能同时从一个管道中读取和写入,
读取和写入要对应两个不同的管道!
4. 匿名管道
对于匿名管道来说,通常用于父子
进程之间的通信,在父进程使用
pipe创建好管道后,再使用fork创建
子进程,此时子进程会将父进程的
文件描述符表给拷贝过来,也就天然
的拥有这两个管道文件了!
并且此时我们会面临两个问题:
- 读取方将文件关闭了会发送什么?
- 读取方在文件中没有数据时会干什么?
读端关闭后,写端进程会终止
当管道无数据时读端会阻塞
有了上面的经验后,现在可以编码验证一下:
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;
}
总结管道的特点:
- 管道常用于父子进程间的通信
- 管道是面向字节流的服务
- 管道是基于文件的,管道的生命周期随进程
- 管道是单向通信的
- 写快读慢,写满管道后不能再写了
- 写慢读快,管道没有数据时,读端要等待
- 写端关闭,读端会读到0,标识结束
- 读端关闭,写端继续写会终止进程
5. 命名管道
匿名管道的一个限制就是必须是在
有血缘关系的进程间才能通信,使用
命名管道可以解决这个问题
匿名管道和命名管道的区别:
- 匿名管道由pipe函数创建并打开。
- 命名管道由mkfifo函数创建,打开用open
- FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。
命名管道的打开规则:
如果当前打开操作是为读而打开FIFO时
- O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO
- O_NONBLOCK enable:立刻返回成功
如果当前打开操作是为写而打开FIFO时
- O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO
- O_NONBLOCK enable:立刻返回失败,错误码为ENXIO
命名管道简单通信:
读端代码:
#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;
}
6. 总结以及拓展
虽然匿名管道和命名管道已经包含了
对于有血缘关系和无血缘关系的进程
的通信,但是毕竟调用read和write这些
系统调用接口会不断的在用户态和内核
态进行切换,比较消耗资源,所以管道不是
最好的!
拓展: 为什么读端关闭后,写端进程会终止?
这是因为当读端关闭后,写端再使用
write操作会产生SIGPIPE信号,此进
程收到此信号进而会终止进程,可以
使用捕捉信号的方式验证这一结论
相关文章:

【linux进程间通信(一)】匿名管道和命名管道
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Linux从入门到精通⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学更多操作系统知识 🔝🔝 进程间通信 1. 前言2. 进程间…...
第11章 jQuery
学习目标 了解什么是jQuery,能够说出jQuery的特点 掌握jQuery的下载和引入,能够下载jQuery并且能够使用两种方式引入jQuery 掌握jQuery的简单使用,能够使用jQuery实现简单的页面效果 熟悉什么是jQuery对象,能够说出jQuery对象与DOM对象的区别 掌握利用选择器获取元素的方法…...

leetcode:1736. 替换隐藏数字得到的最晚时间(python3解法)
难度:简单 给你一个字符串 time ,格式为 hh:mm(小时:分钟),其中某几位数字被隐藏(用 ? 表示)。 有效的时间为 00:00 到 23:59 之间的所有时间,包括 00:00 和 23:59 。 …...

MySQL存储函数与存储过程习题
创建表并插入数据: 字段名 数据类型 主键 外键 非空 唯一 自增 id INT 是 否 是 是 否 name VARCHAR(50) 否 否 是 否 否 glass VARCHAR(50) 否 否 是 否 否 sch 表内容 id name glass 1 xiaommg glass 1 2 xiaojun glass 2 1、创建一个可以统计表格内记录…...

基于 Hologres+Flink 的曹操出行实时数仓建设
本文整理自曹操出行实时计算负责人林震基于 HologresFlink 的曹操出行实时数仓建设的分享,内容主要分为以下六部分: 曹操出行业务背景介绍曹操出行业务痛点分析HologresFlink 构建企业级实时数仓曹操出行实时数仓实践曹操出行业务成果分析未来展望 一、曹…...

【Docker】实战多阶段构建 Laravel 镜像
作者主页: 正函数的个人主页 文章收录专栏: Docker 欢迎大家点赞 👍 收藏 ⭐ 加关注哦! 本节适用于 PHP 开发者阅读。Laravel 基于 8.x 版本,各个版本的文件结构可能会有差异,请根据实际自行修改。 准备 新…...

【MATLAB源码-第118期】基于matlab的蜘蛛猴优化算法(SMO)无人机三维路径规划,输出做短路径图和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 蜘蛛猴优化算法(Spider Monkey Optimization, SMO)是一种灵感来源于蜘蛛猴觅食行为的群体智能优化算法。蜘蛛猴是一种生活在南美洲热带雨林中的灵长类动物,它们在寻找食物时展现出的社会行…...

【计算机组成与体系结构Ⅱ】Tomasulo 算法模拟和分析(实验)
实验5:Tomasulo 算法模拟和分析 一、实验目的 1:加深对指令级并行性及开发的理解。 2:加深对 Tomasulo 算法的理解。 3:掌握 Tomasulo 算法在指令流出、执行、写结果各阶段对浮点操作指令以及 load 和 store 指令进行了什么处…...

Nginx 简介
1、概念介绍 Nginx ("engine x") 是一个轻量级、高性能的 WEB 服务器软件和反向代理服务器。 Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。其将源代码以类 BSD 许可证的形式发…...

C++入门学习(一)写一个helloworld
1、头文件 #include <iostream> using namespace std; 任何程序都需要这两句的,写上就好。 2、主文件 int main() {cout<<"Hello World!"<<endl;return 0; } 由于是int型数据,所以要返回一个值,即return0。…...
ChatGPT 股市知识问答
我 2024-01-17 14:16:38 股市交易的关键指标有哪些? ChatGPT 2024-01-17 14:16:38 股市交易中常用的关键指标有很多,以下是一些常见的指标: 股价指标:股价是衡量股票价格变化的重要指标,包括每股收益(EPS…...

uniapp多端评价页
如图所示:评价页 <template><view><!-- 顶部 --><view class"evaluate_head"><image class"headBg" src"/static/evaluate/head.png" mode""></image><view class"headZindex…...

行为树(Behavior Trees)
行为树(Behavior Trees)是一种在游戏开发中广泛使用的AI设计模式,主要用于描述AI的行为和决策过程,实现更加智能和自然的游戏AI。它由多个节点组成,每个节点代表一个行为或决策,按照特定的方式连接在一起&a…...
opensssl BIO方式https客户端
废话不多说,代码中使用了两种https客户端的实现方式。 #include <windows.h> #include <WinSock.h>#pragma comment(lib,"ws2_32.lib") #include "../include/openssl\ssl.h" #include "../include/openssl\err.h"#pragm…...
JavaScript之判断是否整数、取余、取整、进制、位或、ES6
MENU 方法一方式二方式三方式四方式五结束语 方法一 使用取余运算符判断,利用任何整数都会被1整除的原理,即余数是0的特点,通过这个规则来判断是否是整数。 let isInteger (val) > val % 1 0;// true isInteger(5); // false isInteger(…...

【打造你自己的Shell:编写定制化命令行体验】
本节重点: 学习进程创建,fork/vfork 学习到进程等待 学习到进程程序替换, 微型shell,重新认识shell运行原理 学习到进程终止,认识$? 一、进程创建 1.1.fork函数初识 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程…...

PGSQL主键序列
PostgreSQL和 MySQL数据库还是有一定的区别。 下面了解一下 PGSQL的主键序列。 一、主键 1、系统自带主键序列 在 PostgreSQL 中,GENERATED BY DEFAULT 和 GENERATED ALWAYS 是用于定义自动生成的列(Generated Column)的选项。一般可作用…...

pg14.2迁移至KingbaseV8R6后部分表记录数为空
pg14.2迁移至KingbaseV8R6后部分表记录数为空 问题描述 kdts工具迁移详情里显示表数据已迁移成功,但是迁移后测试发现部份表记录数为空 分别查看源库和目标库表记录数 --源库 select count(*) from aaf_sys_param order by 1; 229条--目录库 select count(*) fr…...

【Spring 篇】深入解析SpringMVC的组件魅力
SpringMVC,这个名字在Java Web开发者的耳边仿佛是一首动听的旋律,携着轻盈的氛围,带给我们一种愉悦的编程体验。但是,当我们深入探寻这个框架时,它的魅力远不止表面的简单,它由许多组件构成,每个…...
HPsocket 在 C# 中的运用:一款优秀的 socket 通信框架
摘要:本文将为您详细介绍 HPsocket,一款适用于 win32 平台的 socket 通信框架。同时,我们还将探讨如何在 C# 项目中使用 HPsocket,实现网络通信功能。通过本文,您将深入了解 HPsocket 的特点、优势以及在 C# 中的实际应…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...