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

【Linux庖丁解牛】— 信号量ipc管理!

1. 并发编程概念铺垫

> 多个执行流【进程】看到同一份资源:共享资源

> 被保护起来的资源叫做临界资源

> 在进程中,涉及临界资源的程序段叫做临界区。【说人话就是程序中访问共享资源的代码】

> 什么是互斥:任何时刻,只允许一个执行流访问资源叫叫作互斥。【比如,一个进程在访问临界资源的时候,另一个进程无法访问,直到前者访问结束解锁,将锁交给后者,后者才能访问临界区!】

> 什么是同步:多个执行流,访问临界资源的时候,具有一定的顺序性,叫做同步。

> 所谓对共享资源的保护,本质上是对共享资源代码的保护【即对临界区的保护】。

2. 认识并理解信号量

什么是信号量呢?信号量本质就是计数器,用来描述临界资源中资源的多少。

我们的进程在访问临界资源时,并不是说,你想访问就访问。其实,临界资源也是分一块一块的,每个进程如果成功访问临界资源,那么这块临界资源就势必会被占用。一旦临界资源被占满了,后来的进程就无法再访问临界资源了。系统又是如何做到这一点的呢?所有进程在访问临界资源之前,都必须要先申请信号量【我们现在可以简单把它理解为一个整形变量的计数器,用来描述临界资源的多少】,一旦申请成功,计数器减减。至此,该进程就可以随时访问系统为其分配的临界资源。但是,如果资源不够,那么该进程就会被阻塞挂起。所以,信号量的本质是对资源的预定机制

细节一:信号量需要被所有进程访问,那么信号量本身就是共享资源。信号量需要被保护起来,那么对于信号量的操作必须是要原子性的。我们把申请信号量,计数器++叫做p操作,进程结束访问临界资源,计数器--叫做v操作。所以,信号量通过PV操作来完成资源的预定机制。【而这两个操作都必须是要原子性的,至于如何保证原子性后面再说】

细节二:只有1和0两态的信号量叫做二元信号量【也就是互斥】

细节三:信号量和通信有什么关系呢?为什么信号量会被归为进程间通信的范畴呢

首先,进程对资源的访问,都必须要先申请信号量,所以进程看到了同一份资源。其次,不只是传递数据才是进程间通信,同步互斥通知也是进程间通信。比如:在进程a申请信号量时,计数器为0,那么进程a申请信号量失败,进程a则阻塞挂起到等待队列中。有朝一日,进程b访问临界资源结束,释放资源,计数器++,进程a看到后被唤醒申请临界资源。在上面这个例子中,进程b通过信号量完成了对进程a的控制

3. 系统如何管理组织ipc

我们前面一直说,系统内部有描述共享内存|消息队列|信号量的结构体对象,我们也可以理解。但是,系统内部是如何管理组织这些结构体对象呢???

不急,我们先来看看一些有关消息队列和信号量的接口:

信号量创建接口:

信号量控制接口:

消息队列创建接口:

 消息队列控制接口:

通过观察以上的接口,我们发现描述这些ipc的结构体对象都有一个共性:就是它们都命名为struct xxxid_ds,并且第一个成员类型都是struct ipc_perm,而且ipc_perm中的第一个成员都是key

因此,我们可以得出一个结论:在Linux内核中,共享内存,消息队列,信号量都用key来唯一区分!并且它们被系统当做了同一种资源。 

事实上,在Linux内核中,有一种全局的数据结构来管理组织ipc,就是struct ipc_ids。其中,entries指针指向ipc_id_ary,ipc_id_ary中有一个结构叫柔性数组

 而该柔性数组中则管理了内核中的所有ipc,无论是共享内存,消息队列还是信号量。但是,系统又是如何区分不同的结构体呢【毕竟柔性数组若是没有相应的类型,我们就这能获得它指向元素的第一个成员】??我们可以这样理解,在创建控制不同类型的ipc时,我们使用的系统调用是不同的,内核中对柔性数组可以因此来区分不同类型的结构体,到时用得到的类型进行强转即可。至此,我们也终于明白了,xxxid为什么在不断的增长,因为他就是柔性数组的下标,我们也不用担心数组下标越界。当下标到达最大值时,管理柔性数组的结构体会对其下标进行回绕。

下面是部分内核图帮我们理解:

http://www.dtcms.com/a/277578.html

相关文章:

  • AI(学习笔记第五课) 使用langchain进行AI开发 load documents(web)
  • 【算法】贪心算法:柠檬水找零C++
  • 基础数论学习笔记
  • 西门子博图PID入门组态编程及调试
  • 代码随想录算法训练营第三十三天|62.不同路径 63. 不同路径 II 343. 整数拆分 96.不同的二叉搜索树
  • Docker(02) Docker-Compose、Dockerfile镜像构建、Portainer
  • SLAM中的非线性优化-2D图优化之激光SLAM cartographer前端匹配(十七)
  • 出现SSL连接错误的原因和解决方案
  • git实际工作流程
  • sql:sql在office中的应用有哪些?
  • 【版本控制】Perforce Helix Core (P4V) 完全入门指南(含虚幻引擎实战)
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频摘要快速生成与检索优化(345)
  • STM32-第六节-TIM定时器-2(输出比较)
  • DNS协议解析过程
  • 【OpenGL ES】手撕一个mini版的Android native渲染框架
  • Linux系统移植19:根文件系统的构建
  • ReAct论文解读(1)—什么是ReAct?
  • (懒人救星版)CNN_Kriging_NSGA2_Topsis(多模型融合典范)深度学习+SCI热点模型+多目标+熵权法 全网首例,完全原创,早用早发SCI
  • C语言关键字---枚举
  • LeetCode|Day8|1047. 删除字符串中的所有相邻重复项|Python刷题笔记
  • 基于YOLOv3-Tiny 的智能门铃的人体检测模型的实现(中)
  • PS2025最新稳定版下载安装详细图文教程(附安装包)
  • STM32 | HC-SR04 超声波传感器测距
  • 万丈高楼平地起:开发环境搭建与“Hello, World”
  • STM32中EXTI(外部中断)详解
  • Vue中的render()函数
  • word中多行合一功能实现
  • python基础知识pip配置pip.conf文件
  • Tableau破解安装
  • ROS2---NodeOptions