【Linux:文件 + 进程】进程间通信进阶(2)

【Linux:文件 + 进程】进程间通信进阶(2)

头像

🎬 个人主页艾莉丝努力练剑
专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录
Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享

⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平


🎬 艾莉丝的简介:

在这里插入图片描述

文章目录


在这里插入图片描述

7 ~> 消息队列

7.1 消息队列的概念

这个消息队列是系统层面的概念,不是组件级别的,和未来组件里的消息队列不是一个东西。

所谓的消息队列,就是在操作系统里面维护一个队列结构。

7.2 消息队列的原理

  • 消息队列——操作系统提供的IPC结构。

也会存在一个由用户设置的key值(A、B进程都能够看到),约定好的。

双方通过往消息队列里面插入节点来进行通信。

消息队列在内核中也要存在一个描述结构体。

在这里插入图片描述


消息队列也有自己的结构体,看到自己的键值。

消息队列和共享内存都是系统级的IPC。

如果这个数据节点只有数据,操作系统怎么区分这是A的还是B的?

必须保证这种数据块是有类型的数据块!

  • 消息队列是一种一个进程给另一个进程发送有类型数据块的方式!

我们需要的系统调用:

在这里插入图片描述

7.3 消息队列的接口

在这里插入图片描述


在这里插入图片描述

7.4 消息队列的一些命令

  • 查看消息队列
在这里插入图片描述
  • 删除消息队列
在这里插入图片描述

8 ~> 信号量

在共享内存那里我们知道,使用共享内存的时候,共享内存没有保护机制,信号量可以保护共享内存。

在这里插入图片描述
  • 在共享内存这里先谈理论部分,在线程那里再谈别的。
  • 这里我们重点理解信号量是什么的问题!

8.1 概念补充

在这里插入图片描述

当你学了管道,可能对“看到同一份资源”没有强烈的感觉;但是学了信号量就可以了——

  • 多进程通信,最重要的是让不同的进程看到同一份资源

解决方案:不同的进程看到同一份资源 -> 新的问题也就从这里展开了!

新的解决方案引入新的问题(硬币也有正反、有钱了解决了现在的问题但是又有一大批人来借钱了、……)。

  • 问题:对同一个进程进行访问的时候会出现并发访问出现错误的问题!

比如刚才的两个写端的互相清空覆盖的现象(同时打开两个写端)——互相干扰。

8.1.1 共享资源和临界资源

我们现阶段是处在“并发访问出现错误”的阶段。

  • 我们把多个执行流(进程)能够看到的公共资源叫做共享资源
  • 把被保护起来的资源叫做临界资源。

8.1.2 互斥和同步

  • 任何时刻只允许一个执行流访问资源,就叫做互斥

只允许我一个人访问,比如ATM机器取钱、上厕所关门等等——不想被别人打扰,就是互斥访问——

在这里插入图片描述


ATM机就是这个临界资源,有了顺序性,就是同步。

让多个进程执行的时候一定要有顺序,按顺序执行——同步。

一个进程在等另一个进程。

  • 互斥与同步 + 共享资源 = 临界资源(被保护的共享资源)

8.1.3 和程序员有什么关系?

在这里插入图片描述


不管是同步、互斥,共享资源、临界资源,上面这些工作具体和程序员有什么关系?我程序员就是个写代码的啊!

  • 为了更好地理解,再举一个例子
在这里插入图片描述
  • 父子进程打印内容错乱、没有规律,一会儿打父进程的、一会儿打子进程的。

大家有没有遇到过父子进程都往同一个显示器上面打印消息的时候,发生错乱的这种情况?

这是因为Linux下一切皆文件,stdout其实是一个共享资源,我们父子进程向它打印的时候,这个共享资源是没有被保护起来,所以会出现这种现象,我们要保护的话需要同步与互斥这种机制。所以并发错乱的问题我们早就遇到过了。

  • Linux下一切皆文件,显示器也是文件(设备文件),在这里属于共享资源,这里的显示器是没有被保护的(数据不一致,这里先不说),为了防止【错乱】,要通过同步和互斥来保护显示器这个共享资源。
在这里插入图片描述


在这里插入图片描述

为什么突然说这个?

在这里插入图片描述

8.1.4 临界区和

一定要记住,所谓的共享资源,站在程序员的视角,将来程序员也是通过代码访问共享资源的!

未来程序员所写的代码,有的代码是会访问共享资源,同样的,有的代码不会访问共享资源。

  • 把访问公共资源的代码叫做【临界区】,把不访问公共资源的代码叫做【非临界区】。

在进入临界区之前,进行加锁;离开时,解锁。

  • 通过加锁、解锁——写代码的方式要改,把临界资源保护起来
在这里插入图片描述

8.1.5 保护访问公共资源的代码

  • 保护访问公共资源的代码
在这里插入图片描述

8.1.6 补充概念思维导图

在这里插入图片描述

8.2 信号量的三个问题

一看到问题,我们就会想到高中语文学习时候的三个问题:

  • 是什么?
  • 为什么?
  • 怎么办?

我们学习信号量的时候也可以迁移这种发问的思想。

8.2.1 (概念)信号量是什么?

很多教材里面喜欢管信号量叫做“信号灯”——被翻译过来的。

  • 信号量:用来实现同步和互斥的一种技术。
  • 场景:公共资源 -> 把公共资源当做整体访问(ATM机器),也有局部使用(电影院看电影,一个座位)。
在这里插入图片描述

8.2.2 信号量的本质

  • 信号量本质:是一个计数器,用来衡量临界资源中,资源数量的计数器,可以想象成一个int count——计数器就是信号量的本质。
在这里插入图片描述

8.2.3 理解

我们基本上没见过电影院放印厅因为座位发生争执的,因为电影院就那么多座位也只会放最多这么多人进来。

座位真正属于你的时候,是什么时候?——买票的时候

只要买到了票,必然有座位。

票卖完了也很正常,说明总票数是一个计数器,本身是有上限的,我们可以通过买票的操作对这个计数器进行减减(--)。

  • 1、买票
  • 2、坐在你的座位上-本质上就是你已经开始访问这个资源了

我只要把票买了,这个座位就是属于我了。相当于我提前预定了,其他人不能占我的位置。换言之我只要买了票,就一定会有一个资源属于我。

所以,买票的本质:对共享资源的一种预定机制!

在我们今天来看我们可以把这个放映厅想成内存块。一个个人就是一个个进程。就像我人要买票,每一个进程也需要对应的操作才能访问,也就是先申请信号量,所以我们进入临界区对这个计数器------>P(),走了++,V()。

在这里插入图片描述

申请信号量这个操作的本质就是对临界区资源进行预定。

我们来写一个不太严谨的伪代码来帮助理解一下:

在这里插入图片描述

8.2.4 补充故事:如果今天电影院的放映厅里面只有一个座位呢

在这里插入图片描述

8.2.5 信号是什么的思维导图

在这里插入图片描述

8.2.6 为什么要有信号量?

  • 因为有问题:并发访问 ~> 信号量 ~> 为了解决多进程访问共享资源产生的并发读写问题
在这里插入图片描述

8.2.7 怎么办?

  • 怎么办:我们就来了解一下信号量的一些接口!
  • 怎么设计信号量?
  • 怎么创建信号量?

我们先来看一下信号量的一些接口——

  • 创建信号量:semget
在这里插入图片描述
  • 操作系统允许创建信号集
在这里插入图片描述
  • 信号量集
在这里插入图片描述
  • 删除信号量的系统调用
在这里插入图片描述
  • 共享内存信号量在操作系统角度是怎么被“先描述再组织”的?

我们先来看看信号量集——

在这里插入图片描述


这个5指的是信号量集里面有五个。

  • 信号量本质是个计数器
在这里插入图片描述
  • 对信号量进行操作的时候用semctl不光是删除操作,包括获取、删除、……
在这里插入图片描述
  • 系统提供的枚举类型的结构体传进去就可以处理初始值
在这里插入图片描述


获取信号量集的信息,信号量集的创建时间什么的——

在这里插入图片描述

这个结构体 struct semid_ds 用于描述 System V 信号量集的关联信息。通过它,你可以获得信号量集的创建时间(sem_ctime),同时还能获取以下信息:

在这里插入图片描述
  • 怎么保证看到的是同一个信号量集?
在这里插入图片描述
  • 信号量这里的op和共享内存那里一样,通常是+1或者-1,代表要进行什么操作
在这里插入图片描述
  • sembuf 结构体是 semop() 系统调用用来描述单个信号量操作的核心数据结构。它包含的三个成员 sem_numsem_opsem_flg 分别决定了操作的对象、操作的类型以及行为标志。下面详细解释每个成员的作用。

这个sem_num是什么?

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


我们来看一段作为示例的代码片段:

#include<sys/sem.h>// 假设已经通过 semget() 获得了一个信号量集的标识符 semidstructsembuf sb;// 对信号量集索引为 0 的信号量执行 P 操作(获取资源) sb.sem_num =0;// 第 1 个信号量 sb.sem_op =-1;// 想要减少 1 sb.sem_flg = SEM_UNDO;// 进程退出时自动还原if(semop(semid,&sb,1)==-1){perror("semop");// 错误处理}else{// 成功获取资源,可以进入临界区}
总结一下:sem_num:指定操作哪个信号量(索引)。sem_op:定义增减值或等待条件。sem_flg:控制阻塞行为与自动撤销。

这三个成员共同决定了 semop() 如何修改或等待信号量,是实现进程同步与互斥的基础。

最下面这个回滚就不说啦,很麻烦,上面说的了解一下就行。

  • 信号量创建、开辟空间是分开的!

6.2.8 信号量怎么办的思维导图

在这里插入图片描述

结尾

uu们,本文的内容到这里就全部结束了,艾莉丝在这里再次感谢您的阅读!

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!

往期回顾:

【Linux:文件】进程间通信进阶(1)

🗡博主在这里放了一只小狗,大家看完了摸摸小狗放松一下吧!🗡૮₍ ˶ ˊ ᴥ ˋ˶₎ა

Read more

深入浅出链表:从结构体到数组的两种实现方式

深入浅出链表:从结构体到数组的两种实现方式

深入浅出链表:从结构体到数组的两种实现方式 * 一、链表的基本概念 * 二、结构体实现链表 * 2.1 节点结构定义 * 2.2 链表构建与遍历 * 2.3 结构体实现的优缺点 * 三、数组实现链表 * 3.1 实现原理 * 3.2 代码实现 * 3.3 构建与访问示例 * 3.4 数组实现的性能特点 * 四、两种实现方式对比 * 五、实际应用建议 * 结语 本文 Bilibili 视频地址 链表作为计算机科学中最基础也最重要的数据结构之一,其灵活性和动态性使其在各种场景下都有广泛应用。本文将带你深入探索链表的两种实现方式:经典的结构体实现和高效的数组实现。 一、链表的基本概念 链表是一种线性的、动态的数据结构,由一系列节点(Node)通过指针(或引用)连接而成。

By Ne0inhk
一文详解PPO(Proximal Policy Optimization, 近端策略优化算法)

一文详解PPO(Proximal Policy Optimization, 近端策略优化算法)

一、前言 笔者在初次接触强化学习(Reinforcement Learning,RL)时,便对“让智能体自己学会决策”这个概念产生了浓厚的兴趣。随着近几年深度学习浪潮席卷整个 AI 领域,强化学习也开始和深度网络、生成式大模型等概念有机结合,衍生出诸如AlphaGo、深度Q网络(DQN)、策略梯度、PPO、RLHF(基于人类反馈的强化学习) 等一系列技术与应用。 其中,PPO(Proximal Policy Optimization, 近端策略优化算法) 算法又以其收敛稳定、实现简洁、适用面广泛等特性在业界和学术界获得了大量关注。OpenAI 的多项研究和实践成果都展示了 PPO 在连续动作控制、游戏对战(Atari)以及大语言模型微调等任务中的强大威力。 在大模型的浪潮下,我们也常常看到一些强化学习微调大模型的例子,如用 PPO 去让 ChatGPT 学会根据人类偏好产出更合适的回复,或者让大模型在写代码时更倾向于写出高效算法,这些背后都隐藏着 PPO 算法的身影。

By Ne0inhk
cJSON 1.7.19 源码深度分析:数据结构、解析流程与深度注释实践

cJSON 1.7.19 源码深度分析:数据结构、解析流程与深度注释实践

本文基于 cJSON 1.7.19 源码,从核心数据结构、JSON 解析/生成流程、内存管理到深度注释实践,系统梳理这一轻量级 JSON 库的设计与实现,适合 C 语言进阶与嵌入式开发学习。 目录 * 一、前言 * 二、核心数据结构:cJSON 结构体 * 2.1 结构体定义 * 2.2 内存布局(64 位系统示意) * 2.3 类型系统:位掩码设计 * 2.4 树状链表:一个例子 * 三、核心流程一:JSON 解析(字符串 → cJSON 树) * 3.1 调用链

By Ne0inhk
LeetCode 42接雨水全解:暴力超时→DP降维打击→双指针极限压缩空间→单调栈栈式凹槽定位,全景式解析算法优化路径

LeetCode 42接雨水全解:暴力超时→DP降维打击→双指针极限压缩空间→单调栈栈式凹槽定位,全景式解析算法优化路径

文章目录 * 本篇摘要 * LeetCode 42 接雨水 详解 * ① 暴力解法(多循环嵌套,卡超时,因此后续使用了两种基于暴力优化的方法) * ② 动态规划解法 * 核心思想 * 步骤(三步走) * 举例说明 * 代码实现思路 * ③ 双指针解法(优化对应的dp的空间复杂度变成O(1)) * 双指针优化思路 * ④单调栈解法 * 单调栈简介 * 核心特点 * 常见用途 * 左边最近比当前数大的数(用单调栈) * 步骤: * 示例: * 最终结果: * 单调栈一般模版 * 关键点 * 注意点 * 单调栈不同选型需求 * 优势 * 引入单调栈 * 本篇小结 本篇摘要 本篇围绕LeetCode 42“接雨水”展开,剖析四种解法:暴力法通过嵌套循环统计每柱接水量,易超时;动态规划预先记录左右最大值,将复杂度降至O(n);双指针边遍历边更新极值,空间优化至O(1

By Ne0inhk