【Linux】进程间通信——System V信号量

目录

写在前面的话

一些概念的理解

信号量的引入

信号量的概念及使用


 

写在前面的话

        System V信号量是一种较低级的IPC机制,使用的时候需要手动进行操作和同步。在现代操作系统中,更常用的是POSIX信号量(通过sem_*系列的函数进行操作)或更高级的同步原语(如互斥锁、条件变量等)来实现进程间通信和同步。所以这里只说一下大概的使用过程,不过多详细解释。后面我们会在POSIX信号量中详细讲解。

一些概念的理解

        我们上一篇文章讲了System V共享内存,我们可以知道:

为了让进程间通信 ---> 需要让不同的进程看到同一份资源 ---> 包括之前所有的通信方式,都是优先解决一个问题:让不同的进程看到同一份资源。

        但是让不同的进程看到同一份资源,比如共享内存,会带来一些时序问题,例如写方只写到一半还没写完,读方就读走了,即缺乏访问控制,会造成数据不一致问题。

        管道内部OS已经处理好这些了,所以不需要关心这些时序问题。

        这里,我们

        1.把多个进程(执行流)看到的公共的一份资源 叫做 临界资源

        2.把自己的进程,访问临界资源的代码 叫做临界区

例如上一章的例子:

         所有的代码只有这两行访问临界资源shmaddr了,所以叫做临界区.


使用共享内存时,多个执行流,运行的时候互相干扰。主要是我们不加保护的访问了同样的资源(临界资源)。在非临界区,多个执行流不相互影响的。

        3.为了更好地进行临界区的保护,可以让多执行流在任意时刻,都只能有一个进程进入访问临界区,这就叫做互斥这个互斥后面会在多线程进行详细的讲解.


信号量的引入

        先来说个例子:我们在去看电影时,一定要有座位(放映厅里的一个资源) ,这个座位是不是只有你坐在上面才属于你呢? 很显然不是的,我要先买票,我只要买了票,我就拥有了这个座位,此时不管我人在不在那里,那个座位都是属于我的。

        所以买票的本质:对座位的 |预定| 机制。         

        相应的,每一个进程想进入临界资源,访问临界资源的一部分,不能让进程直接去使用临界资源(不能让用户直接去电影院抢占座位),而是先得申请 信号量(先得买票)。

        信号量的本质是一个计数器,类似int count = n(不太准确例子,目前先这样理解).

        所以申请信号量:

        1.申请信号量本质是:让信号量计数器--

        2.只要申请信号量成功, 临界资源内部一定预留了你想要的资源 --- 申请信号量其实是对临界资源的一种预定机制。

        3.同样地,临界资源使用完成需要释放信号量,本质是信号量++.

        假设一个临界资源中有10份小资源,这个时候 有11个进程,那么前10个进程访问临界资源,申请信号量成功,最后一个进程由于临界资源中资源都在被使用,所以只能阻塞,等待里面进程的资源使用完毕。


        上面一直在说信号量,那信号量到底是什么呢?

        上面提到了信号量是一个计数器,那这个计数器是什么呢?

        首先计数器肯定不可能是局部变量,这样计数器就和每个进程联系不起来了,因为每个进程都有自己的计数器,这就很荒谬了.

        那如果是全局变量,父子进程在申请信号量时,会发生写时拷贝,导致这个变量父子进程各自一份,也不太行。

        那就假设让多个进程看到同一份n,(即n在共享内存中),然后此时大家再申请信号量可以吗?

答案也是不可以的.

        首先我们要知道,计算是在CPU中进行的,而数据n保存在内存中.

CPU执行指令的时候,需要做以下三步:

        1.将内存中的数据加载到cpu的寄存器

        2.n--(分析&&执行指令)

        3.将cpu修改完毕的n写回内存。

        这看起来没什么问题,但是执行流在执行的时候,在任何时刻都可能被切换 。

        被切换的时候,会带走自己的上下文数据(包括n),然后再被切回来的时候,再把自己的上下文数据写入到cpu的寄存器中,继续执行。

这样就有了一个问题:

        假设有10个进程,分别为1,2,3,4...,9,10,而临界资源一共只有5份,所以信号量n也为5.

        假设1先申请信号量,但运气不好执行完第一步,就被切走了,然后2,3,4,5,6都正常申请了信号量,此时信号量已经为0,后面7到10的进程都不能再申请了。

        但此时1号又开始继续执行,由于第一次进来时n是5,继续执行第2,3步,n--为4,然后再写回到内存,此时n从0变成了4,这不就差了吗,明明都没有资源了,结果信号量成了4,后面的进程又可以继续申请,这样肯定就出错了。       

        所以n--因为时序问题导致n有中间状态,可能导致数据不一致、但如果n只有一行汇编,那么该操作就是原子的!

所以4.原子性:要么不做,要么做完,没有中间状态,就称为原子性


信号量的概念及使用

概念:

System V信号量是一种在操作系统中提供的进程间通信(IPC)机制,用于实现进程之间的同步和互斥。它通过对计数器进行操作来控制资源的访问。

System V信号量由一个整型的标识符(semaphore identifier)来标识,每个标识符对应着一个信号量集合(semaphore set)。信号量集合中可以包含多个单独的信号量,每个信号量都有一个非负整数值。

使用:

System V信号量提供了以下三个基本操作:

  1. 创建信号量集合:使用semget()系统调用创建一个新的信号量集合。该调用返回一个信号量标识符,用于后续的信号量操作。

  2. 控制信号量集合:使用semctl()系统调用控制信号量集合。通过该调用,可以设置信号量的初始值、获取或改变信号量的值,以及删除信号量集合等。

  3. 操作信号量:使用semop()系统调用来操作信号量。该调用接受一个信号量标识符和一组操作,可以通过操作来获取或释放信号量,并进行其他的控制操作。

semop()系统调用所接受的操作包括:

  • P(等待)操作:通过对信号量的值进行减一操作(如果信号量值大于零),或者使得调用进程进入等待状态(如果信号量值为零)。
  • V(释放)操作:通过对信号量的值进行加一操作,并唤醒等待该信号量的其他进程。
  • 通过适当的组合和操作,可以实现对资源的互斥访问和并发控制。多个进程可以通过对信号量的操作来协调彼此之间的动作,以保证数据的一致性和正确性。

当介绍System V信号量相关函数时,常用的函数包括semget()semctl()semop()。下面将分别介绍它们的参数及用法:

  1. semget()函数:

    int semget(key_t key, int nsems, int semflg);
    
    • 参数:
      • key:唯一key值,用于标识要创建或获取的信号量集合。
      • nsems:指定信号量集合中信号量的数量。
      • semflg:标志参数,用于指定信号量的创建方式和访问权限。
    • 用法:
      • 通过指定一个键值和其他参数,调用semget()函数可以创建一个新的信号量集合,或者获取一个已经存在的信号量集合。
      • 返回值是一个信号量标识符(semaphore identifier),它用于后续对信号量集合的控制和操作。
  2. semctl()函数:

    int semctl(int semid, int semnum, int cmd, ...);
    
    • 参数:
      • semid:信号量标识符,用于指定要操作的信号量集合。
      • semnum:指定具体的信号量在集合中的索引,用于标识要操作的信号量。
      • cmd:执行的控制命令,用于指定具体的操作。
      • arg:根据不同的命令,需要提供的参数。
    • 用法:
      • semctl()函数用于控制和管理信号量集合。
      • 可以通过指定不同的控制命令(cmd)来实现不同的操作,例如设置信号量的初始值、获取或改变信号量的值,以及删除信号量集合等。
      • 具体的参数(如arg)根据不同的命令而有所不同。
  3. semop()函数:

    int semop(int semid, struct sembuf *sops, unsigned nsops);
    
    • 参数:
      • semid:信号量标识符,用于指定要操作的信号量集合。
      • sops:指向一个sembuf结构体数组的指针,包含了一组操作。
      • nsops:指定操作的数量。
    • 用法:
      • semop()函数用于对信号量进行操作。
      • 通过组合不同的操作,可以实现对信号量的获取、释放等操作。
      • sops参数是一个指向sembuf结构体数组的指针,sembuf结构体定义了每个操作的具体信息,包括信号量的编号、操作类型(P操作或V操作)以及操作标志等。
      • nsops参数指定要执行的操作数量。

其中。sembuf结构体大概如下:

 

sembuf结构体是用于在System V信号量中指定操作的结构体,它包含以下字段:

  1. unsigned short sem_num:指定要操作的信号量在集合中的索引,从0开始计数。
  2. short sem_op:指定要执行的操作。
    • 如果sem_op的值大于0,则表示进行V(释放)操作,即增加信号量的值。
    • 如果sem_op的值小于0,则表示进行P(等待)操作,即减少信号量的值。
    • 如果sem_op的值等于0,则表示进行Z(零)操作,如果信号量的值为0,则等待。该操作通常用于同步操作,以等待某个特定条件的发生。
  3. short sem_flg:用于指定操作的标志。
    • IPC_NOWAIT:如果无法进行操作(例如信号量的值为0且sem_op为负数),则立即返回,不进行等待。
    • SEM_UNDO:系统在进程意外终止时,会自动撤销该进程对信号量的操作,以避免死锁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【雕爷学编程】Arduino动手做(24)---水位传感器模块3

37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&#x…

激活函数总结(五):Shrink系列激活函数补充(HardShrink、SoftShrink、TanhShrink)

激活函数总结(五):Shrink系列激活函数补充 1 引言2 激活函数2.1 HardShrink激活函数2.2 SoftShrink激活函数2.3 TanhShrink激活函数 3. 总结 1 引言 在前面的文章中已经介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PReLU、Swis…

基本动态规划问题的扩展

基本动态规划问题的扩展 应用动态规划可以有效的解决许多问题,其中有许多问题的数学模型,尤其对一些自从57年就开始研究的基本问题所应用的数学模型,都十分精巧。有关这些问题的解法,我们甚至可以视为标准——也就是最优的解法。…

Vue组件库

Vue组件库 ViteVue3TypescriptTSX 1、项目搭建 1.1、创建项目(yarn) D:\WebstromProject>yarn create vite yarn create v1.22.19 [1/4] Resolving packages... [2/4] Fetching packages... [3/4] Linking dependencies... [4/4] Building fresh pa…

为新手和非技术人员提供扩展Web网站提供一个升级指南

本指南总结了扩展的基本原则,从一台服务器扩展到能够服务数百万用户的Web应用程序。它面向在技术领域工作的新手和非开发人员。因此,如果您刚刚部署了您的多云平台VPN设置,那么本文并不适合您。 话不多说,那就让我们开始吧&#x…

基于灰狼优化(GWO)、帝国竞争算法(ICA)和粒子群优化(PSO)对梯度下降法训练的神经网络的权值进行了改进(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

存储过程的学习

1,前言 这是实习期间学习的,我可能是在学校没好好听课,(或者就是学校比较垃,没教这部分,在公司经理让我下去自己学习,太难了,因为是公司代码很多部分都是很多表的操作&#…

SQL Server 查询数据并汇总相关技巧 23.08.08

GROUPING 是一个聚合函数,它产生一个附加的列,当用 CUBE 或 ROLLUP 运算符添加行时,附加的列输出值为1,当所添加的行不是由 CUBE 或 ROLLUP 产生时,附加列值为0。 仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相联系的选择…

基于grpc从零开始搭建一个准生产分布式应用(1) - 开始准备

开始前必读:​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ 本来笔者并不想开设这个系列,因为工作量比较大,另外此专题的技术点也偏简单。最近复盘了下最近的工作,发现一个问题就是各个互联网大厂一般都会有…

AcWing算法提高课-4.2.3一个简单的整数问题2

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 给定一个长度为 N N N 的数列 A A A&#xff0c;以及 M M M 条指令&#xff0c;每条指令可能是以下两种之一&#xff1a; C l r…

嵌入式Linux下LVGL的移植与配置

一.sdk源码下载路径 1.官方源码下载路径如下: ​​​​​​ https://github.com/lvgl/lvgl git下载方式 git clone https://github.com/lvgl/lvgl.git 2.个人移植好的源码8.2版本下载路径: 链接&#xff1a;https://pan.baidu.com/s/1jyqIennsQpv-RB4RyKvZyg?pwdc68e 提取…

Spring-Cloud-Loadblancer详细分析_2

LoadBalancerClients 终于分析到了此注解的作用&#xff0c;它是实现不同服务之间的配置隔离的关键 Configuration(proxyBeanMethods false) Retention(RetentionPolicy.RUNTIME) Target({ ElementType.TYPE }) Documented Import(LoadBalancerClientConfigurationRegistrar…

电脑开不了机如何解锁BitLocker硬盘锁

事情从这里说起&#xff0c;不想看直接跳过 早上闲着无聊&#xff0c;闲着没事干&#xff0c;将win11的用户名称改成了含有中文字符的用户名&#xff0c;然后恐怖的事情发生了&#xff0c;蓝屏了… 然后就是蓝屏收集错误信息&#xff0c;重启&#xff0c;蓝屏收集错误信息&…

基于深度学习的3D城市模型增强【Mask R-CNN】

在这篇文章中&#xff0c;我们描述了一个为阿姆斯特丹 3D 城市模型自动添加门窗的系统&#xff08;可以在这里访问&#xff09;。 计算机视觉用于从城市全景图像中提取有关门窗位置的信息。 由于这种类型的街道级图像广泛可用&#xff0c;因此该方法可用于较大的地理区域。 推荐…

如何把图片转成gif?一分钟学会在线一键生成gif

平时我们在聊天的时候&#xff0c;经常会发送一下有趣的表情包&#xff0c;这些表情包是怎么做出来的呢&#xff1f;其实可以使用在线gif生成的方法&#xff0c;下面就来给大家演示一下图片制作gif&#xff08;https://www.gif.cn&#xff09;的具体步骤&#xff0c;一起来看看…

Flink学习记录

可以快速搭建一个Flink编写程序 mvn archetype:generate \-DarchetypeGroupIdorg.apache.flink \-DarchetypeArtifactIdflink-quickstart-java \-DarchetypeVersion1.17.1 \-DgroupIdcom.zxx.langhuan \-DartifactIdlanghuan-flink \-Dversion1.0.0-SNAPSHOT \-Dpackagecom.zx…

《全生命周期眼健康管理》助力健康科学用眼

8月8日下午&#xff0c;烟台正大光明眼科医院眼健康管理中心张提主任受邀来到烟台市残疾人事务综合服务中心&#xff0c;为残联康复训练教师及相关工作人员进行了《全生命周期眼健康管理》讲座。 烟台正大光明眼科医院眼健康管理中心张提主任 “全生命周期眼健康”这一理念其宗…

流水线时序调度之规避冲突

1 写在前面的&#xff1a; 其实略微一个大点的机器&#xff0c;一个测试流程需要若干个步骤&#xff0c;都可以用流水线的思维去看待它&#xff1b; 我之前也没往流水线的角度去考虑&#xff0c;那有些机器的时序调度是不好理解的&#xff0c;甚至计算个通量都很麻烦&#xff…

15-1_Qt 5.9 C++开发指南_Qt多媒体模块概述

多媒体功能指的主要是计算机的音频和视频的输入、输出、显示和播放等功能&#xff0c;Qt 的多媒体模块为音频和视频播放、录音、摄像头拍照和录像等提供支持&#xff0c;甚至还提供数字收音机的支持。本章将介绍 Qt 多媒体模块的功能和使用。 文章目录 1. Qt 多媒体模块概述2. …

pgAdmin开发工具之ERD

pgAdmin 是一个免费的 PostgreSQL 管理与开发平台&#xff0c;这篇文章介绍了它的安装与使用。 今天我们要介绍的是它的一个开发功能&#xff1a;实体关系图&#xff08;ERD&#xff09;工具。 ERD 工具可以使用图形化的方式表示数据库中的表、字段以及表之间的关系。 pgAdmin…