9.进程间通信

news2025/6/8 18:32:31

1.简介

为啥要有进程间通信?

如果未来进程之间要协同呢?一个进程要把自己的数据交给另一个进程!进程是具有独立性的,所以把一个进程的数据交给另一个进程----基本不可能!必须通信起来,就必须要有另一个人的参与:操作系统!

进程间通信的前提(也是本质):先要让不同的进程,看到同一份资源!!

1. 进程间通信⽬的
• 数据传输:⼀个进程需要将它的数据发送给另⼀个进程
• 资源共享:多个进程之间共享同样的资源。
• 通知事件:⼀个进程需要向另⼀个或⼀组进程发送消息,通知它(它们)发⽣了某种事件(如进
程终⽌时要通知⽗进程)。
• 进程控制:有些进程希望完全控制另⼀个进程的执⾏(如Debug进程),此时控制进程希望能够
拦截另⼀个进程的所有陷⼊和异常,并能够及时知道它的状态改变。

2. 进程间通信发展

• 管道(基于文件的通信方法)
• System V进程间通信(单独设计通信模块)
• POSIX进程间通信(网络间进程通信)

3. 进程间通信分类
管道
• 匿名管道pipe
• 命名管道

System V IPC
• System V 消息队列
• System V 共享内存
• System V 信号量

POSIX IPC
• 消息队列
• 共享内存
• 信号量
• 互斥量
• 条件变量
• 读写锁

2.管道

vscode中ctrl + · (esc下面的)即可调出linux命令行界面

我们把从一个进程连接到另一个进程的一个数据流称为一个 “管道”;

管道是一个基于文件系统的内存级的单向通信的文件,主要用来进行进程间通信(IPC)的

3.匿名管道(没有文件路径,没有文件名)

#include <unistd.h>
功能:创建⼀⽆名管道
原型
int pipe(int fd[2]);
参数
fd:⽂件描述符数组,其中fd[0]表⽰读端, fd[1]表⽰写端
返回值:成功返回0,失败返回错误代码
管道的4种情况和5大特性

匿名管道特性:
1.常用与具有血缘关系的进程,进行IPC,常用于父子
2.单向通信
3.管道的生命周期随进程
4.面向字节流-》网络重点
5.管道自带同步机制-》多线程

4种情况:
1.管道里没有数据,读端就会被阻塞(写端不关,写端不写)
2.读端不读,读端也不关(写满了就不再写入了)
3.写端不写,写端关闭:read会读到返回值为0,表示读到文件结尾!
4.读关闭,写正常:OS会自动杀掉写进程!!!(因为OS不会做无效动作)
单次向管道里面写入,写入的字节数小于PIPE_BUF,写入操作就是原子的(不可被分割的,要么不做
,要做就做完,没有第三状态)
Linux 系统:PIPE_BUF的值为 4096 字节 。
如果希望写操作具有原子性,要确保单次写入数据量不超过PIPE_BUF字节

3.1 实例代码 

3.2 用 fork 来共享管道原理

3.3 站在文件描述符角度-理解管道 

3.4 站在内核角度-管道本质

所以,看待管道,就如同看待文件一样!管道的使用和文件一致--“linux一切皆文件的思想” 

3.5 创建进程池处理任务

补充:C++的后缀可以是.cpp,.cc,.cxx
.hpp是用来实现库的,一般是开源库(头源不分离)

轮询或者随机数或者load计数器 --- 负载均衡!!
避免让一个或者个别进程一直都很忙,其他进程一直都很闲

 封装一下:

这里有一个引用计数的BUG 

创建第二个往后的子进程时虽然每次都消除了无关的rw,但是每次新的子进程都把上一次的w继承下来了,使得每次新建一个子进程,往上的父进程写w的引用计数都会+1,这样导致不能按照正常顺序进行close,引用计数不为0关不掉。所以可以倒着关!

4.命名管道

• 管道应⽤的⼀个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。
• 如果我们想在不相关的进程之间交换数据,可以使⽤FIFO⽂件来做这项⼯作,它经常被称为命名
管道。
• 命名管道是⼀种特殊类型的⽂件
匿名管道与命名管道的区别
• 匿名管道由pipe函数创建并打开。
• 命名管道由mkfifo函数创建,打开⽤open
• FIFO(命名管道)与pipe(匿名管道)之间唯⼀的区别在它们创建与打开的⽅式不同,⼀但这些
⼯作完成之后,它们具有相同的语义。
命名管道的打开规则

• 如果当前打开操作是为读⽽打开FIFO时
◦ O_NONBLOCK disable:阻塞直到有相应进程为写⽽打开该FIFO
◦ O_NONBLOCK enable:⽴刻返回成功
• 如果当前打开操作是为写⽽打开FIFO时
◦ O_NONBLOCK disable:阻塞直到有相应进程为读⽽打开该FIFO
◦ O_NONBLOCK enable:⽴刻返回失败,错误码为ENXIO

总的来说:命名管道主要解决,毫无关系的进程之间,进行文件级进程通信!!!

剩下的特点,匿名和命名管道的特点相同

mkfifo创建命名管道 

unlink 通常是一个用于删除文件或解除链接的函数 

效果:两端同步 

 代码实现:

5.system V共享内存

共享内存区是最快的IPC(进程间通信)形式。⼀旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执⾏进⼊内核的系统调⽤来传递彼此的数据

 进程结束了,如果没有进行删除共享内存,共享内存(用ipcs查看)资源会一直存在 --- 共享内存的资源,生命周期随内核!! ----- 如果没有显式的删除,即使进程退出了,IPC资源依旧被占用

 

5.1 相关函数

key vs shmid
1.key: 只有内核使用,用来标识shm的唯一性
2.shmid:给用户用,用来进行访问shm

shmat函数

功能:将共享内存段连接到进程地址空间
原型    //void* 起始虚拟地址
        void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
        shmid: 共享内存的标识符
        shmaddr:指定连接的地址(虚拟地址,固定地址进行挂接)
        shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回⼀个指针,指向共享内存第⼀个节;失败返回-1

说明:
shmaddr为NULL,核⼼⾃动选择⼀个地址
shmaddr不为NULL且shmflg⽆SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会⾃动向下调整为SHMLBA的整数倍。
公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表⽰连接操作⽤来只读共享内存
shmdt函数

功能:将共享内存段与当前进程脱离
原型
        int shmdt(const void *shmaddr);
参数
        shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl函数

功能:⽤于控制共享内存
原型
        int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
        shmid:由shmget返回的共享内存标识码
        cmd:将要采取的动作(有三个可取值)
        buf:指向⼀个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

IPC_STAT:把shmid_ds结构中的数据设置为共享内存的当前关联值

IPC_SET:在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值

IPC_RMID:删除共享内存段

5.2 代码实现共享内存通信:

 

6.system V消息队列(了解)

#消息队列的生命周期也随内核

6.2 相关调用接口

 6.3 数据不一致问题

7.system V信号量(了解)

• 多个执⾏流(进程), 能看到的同⼀份公共资源:共享资源
• 被保护起来的资源叫做临界资源
• 保护的⽅式常⻅:互斥与同步
• 任何时刻,只允许⼀个执⾏流访问资源,叫做互斥
• 多个执⾏流,访问临界资源的时候,具有⼀定的顺序性,叫做同步
• 系统中某些资源⼀次只允许⼀个进程使⽤,称这样的资源为临界资源或互斥资源。
• 在进程中涉及到互斥资源的程序段叫临界区。你写的代码=访问临界资源的代码(临界区)+不访问
临界资源的代码(⾮临界区)
• 所谓的对共享资源进⾏保护,本质是对访问共享资源的代码进⾏保护

7.1 理解

信号量:信号灯,本质是一个计数器,用来表明临界资源中,资源数量的多少;所有进程,访问临界资源中的一小块前,就必须先申请信号量;申请信号量的本质是:对资源的预定机制;资源就给你了,等你随时访问,没人和你抢。

借助电影院理解信号量:

买票:买到票了,该座位就是我的了,即使我不来,该座位也要为我预留。

买票本质是对资源的预定机制!-> 想要访问临界资源,都得先买票(即减少相应信号量)

细节1:信号量本身就是共享资源:申请 --,原子性(P操作);sem++,原子性(V操作)

 细节2:信号量只有1或者0两态的信号量,叫做二元信号量(就是互斥--共享资源整体使用)

 7.2 相关函数

信号量和通信有什么关系?

1. 先访问信号量P,每个进程都得先看到同一个信号量!!(system V 解决的就是这个问题)

2. 不是传递数据,才是通信IPC,通知,同步互斥也!

OS内部存在大量的信号量集合->也要对信号量进行管理->先描述,在组织

可以看出,共享内存,消息队列,信号量 -> key区分唯一性! -> OS中,共享内存,消息队列,信号量,被当作了用一种资源!!! (统称位system V IPC)

8.内核是如何组织管理IPC资源的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React 基础入门笔记

一、JSX语法规则 1. 定义虚拟DOM时&#xff0c;不要写引号 2.标签中混入JS表达式时要用 {} &#xff08;1&#xff09;.JS表达式与JS语句&#xff08;代码&#xff09;的区别 &#xff08;2&#xff09;.使用案例 3.样式的类名指定不要用class&#xff0c;要用className 4.内…

压测软件-Jmeter

1 下载和安装 1.1 检查运行环境 Jmeter需要运行在java环境&#xff08;JRE 或 JDK&#xff09;中 在window的"命令提示窗"查看安装的java版本: java -version 1.2 下载Jmeter 从Apache官网下载Jmeter安装包 1.3 解压和运行 解压后,进入bin文件夹,双击jmeter.bat即可…

NLP学习路线图(三十):微调策略

在自然语言处理领域,预训练语言模型(如BERT、GPT、T5)已成为基础设施。但如何让这些“通才”模型蜕变为特定任务的“专家”?微调策略正是关键所在。本文将深入剖析七种核心微调技术及其演进逻辑。 一、基础概念:为什么需要微调? 预训练模型在海量语料上学习了通用语言表…

leetcode刷题日记——1.组合总和

解答&#xff1a; class Solution { public:void dfs(vector<int>& candidates, int target, vector<vector<int>>& ans, vector<int>& combine, int idx) {if(idxcandidates.size()){//遍历完的边界return;}if(target0){//找完了能组成和…

关于单片机的基础知识(一)

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于单片机基础知识的相关内容&#xf…

Xilinx FPGA 重构Multiboot ICAPE2和ICAPE3使用

一、FPGA Multiboot 本文主要介绍基于IPROG命令的FPGA多版本重构&#xff0c;用ICAP原语实现在线多版本切换。需要了解MultiBoot Fallback点击链接。 如下图所示&#xff0c;ICAP原语可实现flash中n1各版本的动态切换&#xff0c;在工作过程中&#xff0c;可以通过IPROG命令切…

Redis专题-基础篇

题记 本文涵盖了Redis的各种数据结构和命令&#xff0c;Redis的各种常见Java客户端的应用和最佳实践 jedis案例github地址&#xff1a;https://github.com/whltaoin/fedis_java_demo SpringbootDataRedis案例github地址&#xff1a;https://github.com/whltaoin/springbootData…

springMVC-11 中文乱码处理

前言 本文介绍了springMVC中文乱码的解决方案&#xff0c;同时也贴出了本人遇到过的其他乱码情况&#xff0c;可以根据自身情况选择合适的解决方案。 其他-jdbc、前端、后端、jsp乱码的解决 Tomcat导致的乱码解决 自定义中文乱码过滤器 老方法&#xff0c;通过javaW…

【iOS安全】iPhone X iOS 16.7.11 (20H360) WinRa1n 越狱教程

前言 越狱iPhone之后&#xff0c;一定记得安装一下用于屏蔽更新的描述文件&#xff08;可使用爱思助手&#xff09; 因为即便关闭了自动更新&#xff0c;iPhone仍会在某些时候自动更新系统&#xff0c;导致越狱失效&#xff1b;更为严重的是&#xff0c;更新后的iOS版本可能是…

智能标志桩图像监测装置如何守护地下电缆安全

在现代城市基础设施建设中&#xff0c;大量电缆、管道被埋设于地下&#xff0c;这虽然美化了城市景观&#xff0c;却也带来了新的安全隐患。施工挖掘时的意外破坏、自然灾害的影响&#xff0c;都可能威胁这些"城市血管"的安全运行。 传统的地下设施标识方式往往只依…

【网站建设】网站 SEO 中 meta 信息修改全攻略 ✅

在做 SEO 优化时,除了前一篇提过的Title之外,meta 信息(通常指 <meta> 标签)也是最基础、最重要的内容之一,主要包括: <meta name="description"> <meta name="keywords"> 搜索引擎重点参考这些信息,决定你网页的展示效果与排名。…

计算机视觉处理----OpenCV(从摄像头采集视频、视频处理与视频录制)

一、采集视频 VideoCapture 用于从视频文件、摄像头或其他视频流设备中读取视频帧。它可以捕捉来自 多种源的视频。 cv2.VideoCapture() 打开摄像头或视频文件。 cap cv2.VideoCapture(0) # 0表示默认摄像头&#xff0c;1是第二个摄像头&#xff0c;传递视频文件路径也可以 …

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- 第一篇:MIPI CSI-2基础入门

第一篇&#xff1a;MIPI CSI-2基础入门 1. 为什么需要CSI-2&#xff1f; 痛点场景对比 &#xff08;用生活案例降低理解门槛&#xff09; 传统并行接口CSI-2接口30根线传输720P图像仅需5根线&#xff08;1对CLK4对DATA&#xff09;线距&#xff1e;5cm时出现重影线缆可长达1…

变幻莫测:CoreData 中 Transformable 类型面面俱到(一)

概述 各位似秃似不秃小码农们都知道&#xff0c;在苹果众多开发平台中 CoreData 无疑是那个最简洁、拥有“官方认证”且最具兼容性的数据库框架。使用它可以让我们非常方便的搭建出 App 所需要的持久存储体系。 不过&#xff0c;大家是否知道在 CoreData 中还存在一个 Transfo…

开源技术驱动下的上市公司财务主数据管理实践

开源技术驱动下的上市公司财务主数据管理实践 —— 以人造板制造业为例 引言&#xff1a;财务主数据的战略价值与行业挑战 在资本市场监管日益严格与企业数字化转型的双重驱动下&#xff0c;财务主数据已成为上市公司财务治理的核心基础设施。对于人造板制造业而言&#xff0…

Java建造者模式(Builder Pattern)详解与实践

一、引言 在软件开发中&#xff0c;我们经常会遇到需要创建复杂对象的场景。例如&#xff0c;构建一个包含多个可选参数的对象时&#xff0c;传统的构造函数或Setter方法可能导致代码臃肿、难以维护。此时&#xff0c;建造者模式&#xff08;Builder Pattern&#xff09;便成为…

win32相关(IAT HOOK)

IAT HOOK 什么是IAT Hook&#xff1f; IAT Hook&#xff08;Import Address Table Hook&#xff0c;导入地址表钩子&#xff09;是一种Windows平台下的API钩取技术&#xff0c;通过修改目标程序的导入地址表(IAT)来拦截和重定向API调用 在我们之前学习pe文件结构的导入表时&am…

零基础玩转物联网-串口转以太网模块如何快速实现与TCP服务器通信

目录 1 前言 2 环境搭建 2.1 硬件准备 2.2 软件准备 2.3 驱动检查 3 TCP服务器通信配置与交互 3.1 硬件连接 3.2 开启TCP服务器 3.3 打开配置工具读取基本信息 3.4 填写连接参数进行连接 3.5 通信测试 4 总结 1 前言 TCP是TCP/IP体系中的传输层协议&#xff0c;全称为Transmiss…

ESP32开发之LED闪烁和呼吸的实现

硬件电路介绍GPIO输出模式GPIO配置过程闪烁灯的源码LED PWM的控制器(LEDC)概述LEDC配置过程及现象整体流程 硬件电路介绍 电路图如下&#xff1a; 只要有硬件基础的应该都知道上图中&#xff0c;当GPIO4的输出电平为高时&#xff0c;LED灯亮&#xff0c;反之则熄灭。如果每间…

【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录

【产品业务设计】支付业务设计规范细节记录&#xff0c;含订单记录、支付业务记录、支付流水记录 前言 我为什么要写这个篇文章 总结设计经验生成设计模板方便后期快速搭建 一个几张表 一共5张表&#xff1b; 分别是&#xff1a; 订单主表&#xff1a;jjy_orderMain订单产…