【Linux】学习记录_12_system-V IPC 信号量

12 system-V IPC 信号量

12.1 进程信号量基本概念

信号量本质是计数器,用于协调多进程间对共享数据对象的读取,不以传送数据为目的, 主要用来保护共享资源(信号量也属于临界资源),使该临界资源在一个时刻只有一个进程独享。

12.2 信号量的工作原理

信号量只能进行两种操作:等待(P操作)和发送信号(V操作),锁就是P操作,解锁就是V操作。 PV操作是计算机操作系统需要提供的基本功能之一,它们的行为是这样的:

  • P 操作:若有可用的资源(信号量值大于0),则占用一个资源(信号量值减一,进入临界区); 若无可用的资源(信号量值为0),则阻塞,直到系统将资源分配给该进程(进入等待队列,一直等到资源轮到该进程)。

  • V 操作:如果在该信号量的等待队列中有进程在等待资源,则唤醒一个阻塞的进程。如果没有进程等待它, 则释放一个资源(给信号量值加一)。

在信号量进行PV操作时都为原子操作(因为它需要保护临界资源)。

注:原子操作:单指令的操作称为原子的,单条指令的执行是不会被打断的

内核可对信号量(计数器)做加减操作,并且操作时遵守一些基本操作原则, 即:对计数器做加操作立即返回,做减操作要检查计数器当前值是否可减?(这个计数器的值要大于1), 如果是则进行减操作;否则将进程将阻塞等待,直到系统中有进程对该信号量进行P操作。

12.2.1 创建或获取一个信号量
12.2.2 semget创建/获取函数

semget函数的功能是创建或者获取一个已经创建的信号量,如果成功则返回对应的信号量标识符, 失败则返回-1。函数原型如下:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>int semget(key_t key, int nsems, int semflg);

参数说明:

  • key:参数key标识系统内信号量, 如果指定key已经存在,则意味着打开这个信号量,这时nsems参数指定为0,semflg参数也指定为0。 特别地,可以使用IPC_PRIVATE创建一个没有key的信号量。

  • nsems:本参数用于在创建信号量的时候,表示可用的信号量数目。

  • semflg:semflg参数用来指定标志位, 主要有IPC_CREAT,IPC_EXCL和权限mode,其中使用IPC_CREAT标志创建新的信号量, 即使该信号量已经存在(具有同一个键值的信号量已在系统中存在),也不会出错。 如果同时使用IPC_EXCL标志可以创建一个新的唯一的信号量,此时如果该信号量已经存在, 该函数会返回出错

创建信号量时,还受到以下系统信息的影响:

  • SEMMNI:系统中信号量总数的最大值。

  • SEMMSL:每个信号量中信号量元素个数的最大值。

  • SEMMNS:系统中所有信号量中的信号量元素总数的最大值。

在Linux系统中,以上信息可通过命令 ipcs -l 查看.

12.3 信号量操作

12.3.1 semop() PV操作函数

Linux提供了semop()函数对信号量进行PV操作。函数原型如下:

int semop(int semid, struct sembuf *sops, size_t nsops);

参数说明:

  • semid:System V信号量的标识符,用来标识一个信号量。

  • sops:是指向struct sembuf结构体数组的指针,该数组是一个信号量操作数组。原型如下:

    struct sembuf
    {unsigned short int sem_num;   /* 信号量的序号从0 ~ nsems-1 */short int sem_op;            /* 对信号量的操作,>0, 0, <0 */short int sem_flg;            /* 操作标识:0, IPC_WAIT, SEM_UNDO */
    };
    
    • sem_num用于标识信号量中的第几个信号量,0表示第1个,1表示第2个,nsems -1表示最后一个。

    • sem_op标识对信号量的所进行的操作类型。对信号量的操作有三种类型:

      • sem_op 大于 0,表示进程对资源使用完毕,对该信号量执行V操作,交回的资源数由sem_op决定, 系统会把sem_op的值加到该信号量的信号量当前值semval上。 特别地,如果sem_flag指定了SEM_UNDO(还原)标志,则从该进程的此信号量调整值中减去sem_op。

      • sem_op 小于 0,表示进程希望使用资源,对该信号量执行P操作,

      • sem_op 等于 0,表示进程要阻塞等待,直至信号量当前值semval 变为 0。

    • sem_flg,信号量操作的属性标志,可以指定的参数包括IPC_NOWAIT和SEM_UNDO。如果为0, 表示正常操作;当指定了SEM_UNDO,那么将维护进程对信号量的调整值,进程退出的时候会自动还原它对信号量的操作; 当指定了IPC_WAIT,使对信号量的操作时非阻塞的。即指定了该标志,调用进程在信号量的值不满足条件的情况下不会被阻塞, 而是直接返回-1,并将errno设置为EAGAIN。

      信号量调整值呢:其实就是指定信号量针对某个特定进程的调整值。只有sembuf结构的sem_flag指定为SEM_UNDO后, 信号量调整值才会随着sem_op而更新。讲简单一点:对某个进程,在指定SEM_UNDO后,对信号量的当前值的修改都会反应到信号量调整值上, 当该进程终止的时候,内核会根据信号量调整值重新恢复信号量之前的值,SEM_UNDO操作可以防止进程退出时没有释放信号量导致的死锁。

  • nsops:表示上面sops数组的数量,如只有一个sops数组,nsops就设置为1。

12.3.2. semctl()属性函数

semctl函数主要是对信号量集的一系列控制操作,根据操作命令cmd的不同,执行不同的操作,第四个参数是可选的。原型如下:

int semctl(int semid, int semnum, int cmd, ...);
  • semid:System V信号量的标识符;

  • semnum:表示信号量集中的第semnum个信号量。它的取值范围: 0 ~ nsems-1 。

  • cmd:操作命令,主要有以下命令:

    • IPC_STAT:获取此信号量集合的semid_ds结构,存放在第四个参数的buf中。

    • IPC_SET:通过第四个参数的buf来设定信号量集相关联的semid_ds中信号量集合权限为sem_perm中的uid,gid,mode。

    • IPC_RMID:从系统中删除该信号量集合。

    • GETVAL:返回第semnum个信号量的值。

    • SETVAL:设置第semnum个信号量的值,该值由第四个参数中的val指定。

    • GETPID:返回第semnum个信号量的sempid,最后一个操作的pid。

    • GETNCNT:返回第semnum个信号量的semncnt。等待semval变为大于当前值的线程数。

    • GETZCNT:返回第semnum个信号量的semzcnt。等待semval变为0的线程数。

    • GETALL:去信号量集合中所有信号量的值,将结果存放到的array所指向的数组。

    • SETALL:按arg.array所指向的数组中的值,设置集合中所有信号量的值。

  • 第四个参数可选:如果使用参数,该参数的类型为 union semun,它是多个特定命令的联合体,具体如下:

    union semun
    {int              val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */
    };
    

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

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

相关文章

microk8s拉取pause镜像卡住

前几天嫌服务器上镜像太多占空间&#xff0c;全部删掉了&#xff0c;今天看到 microk8s 更新了 1.30 版本&#xff0c;果断更新&#xff0c;结果集群跑不起来了。 先通过 microk8s.kubectl get pods --all-namespaces 命令看看 pod 状态。 如上图可以看到&#xff0c;所有的业…

JS -关于对象相关介绍

在JS中&#xff0c;除去基本的数据类型&#xff0c;还有包含对象这种复合数据类型&#xff0c;他可以储存多个键值对&#xff0c;并且每个键都是唯一的&#xff0c;并且在对象中可以包含各种数据类型的值&#xff0c;包括其他对象&#xff0c;数组&#xff0c;函数等。对象是Ja…

Spring Boot 中整合 Redisson 实现分布式锁

添加 Redisson 依赖&#xff1a;在 pom.xml 文件中添加 Redisson 的依赖。 配置 Redis 连接信息&#xff1a;在 application.properties 或 application.yml 文件中配置 Redis 的连接信息。 使用 Redisson 实现分布式锁&#xff1a;在预减库存的地方使用 Redisson 提供的分布…

LeetCode in Python 72. Edit Distance (编辑距离)

编辑距离的基本思想很直观&#xff0c;即不断比较两个单词每个位置的元素&#xff0c;若相同则比较下一个&#xff0c;若不同则需要考虑从插入、删除、替换三种方法中选择一个最优的策略。涉及最优策略笔者最先想到的即是动态规划的思想&#xff0c;将两个单词的位置对应放在矩…

C语言例题(递归、二分查找、冒泡排序)

一、递归案例 有5个人坐在在一起&#xff0c;问第5个人多少岁&#xff1f;他说比第4个人大两岁。问第4个人岁数&#xff0c;他说比第3个人大两岁。问第3个人&#xff0c;又说比第2个人大两岁。问第2个人&#xff0c;说比第1个人大2岁。最后问第1个人&#xff0c;他说是10岁。请…

Vue2 移动端(H5)项目封装弹窗组件

前言 因vant-ui的dialog组件没有自定义footer插槽 效果 参数配置 1、代码示例&#xff1a; <t-dialog :visible.sync"show" :title"title" submit"submit"></t-dialog>2、配置参数&#xff08;t-dialog Attributes&#xff09; 参…

IS62C256AL-45TLI功能参数介绍及如何优化性能

IS62C256AL-45TLI功能和参数介绍及如何优化性能-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 产品品种:静态随机存取存储器 RoHS:是 存储容量:256 kbit 组织:32 k x 8 访问时刻:45 ns 接口类型:Parallel 电源电压-最大:5.5 V 电源电压-最小:4.5 V 电源电流—最大值:25 mA 最小…

python内置函数help()详解

Python 内置函数 help() 1. 概述 help() 是 Python 中的一个内置函数&#xff0c;它提供了一个非常有用的帮助系统。通过这个函数&#xff0c;我们可以获取模块、类、方法、函数等对象的详细帮助信息。这些信息通常包括对象的文档字符串&#xff08;docstring&#xff09;、参…

JumpServer搭建堡垒机实战

文章目录 第一步、下载安装第二步、访问异常处理【1】docker方式拉取失败 JumpServer是运维人员可连接内部服务器上进行操作&#xff0c;支持Linux等操作系统的管理工具。 第一步、下载安装 curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver/releases/latest/…

OpenCV-复数矩阵点乘ComplexMatrixDotMultiplication

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 需求说明 一般用到FFT&#xff0c;就涉及到复数的计算&#xff0c;为了便于调用&#xff0c;我自行封装了一个简单的复数矩阵点乘…

Flutter本地化存储介绍与使用

Flutter提供了多种本地化存储方案&#xff0c;可满足不同应用场景的需求。本文将介绍Flutter中常用的本地化存储方案&#xff0c;并演示如何使用它们存储和读取数据。 1. SharedPreferences SharedPreferences是Flutter中最常用的本地化存储方案之一&#xff0c;它用于存储键…

rror while loading shared libraries: libssl.so.10 亲测有效

wget https://vault.centos.org/centos/8/AppStream/x86_64/os/Packages/compat-openssl10-1.0.2o-3.el8.x86_64.rpm rpm -ivh compat-openssl10-1.0.2o-3.el8.x86_64.rpm

如何用网页绘制一个黑莓9900的键盘效果图

如何用网页绘制一个黑莓9900的键盘效果图 入了几个黑莓蓝牙键盘&#xff0c;出于喜好&#xff0c;想做一个跟实体键盘一模一样的网页界面。 最终的实现效果是这样的&#xff1a; 在线查看&#xff1a;http://kylebing.cn/tools/bb-keyboard 点击上面四个按键显示不同模型界面…

各种指标计算

字错误率&#xff08;cer&#xff09; 使用于中文等不以空格为分隔的语言 import evaluatemetric evaluate.load("cer") print(metric.compute(predictions[你吃了吗, 今天我要去打篮球], references["我吃了么a" , 明天我要去打篮球])) 词错误率&…

PyQt介绍——动画使用详解之动画组QAnimationGroup

QAnimationGroup&#xff1a;动画组&#xff0c;可以包含多个动画&#xff0c;可以包含子动画组。 QSequentialAnimationGroup&#xff1a;顺序动画组&#xff0c;按照添加的顺序依次执行动画。 QParallelAnimationGroup&#xff1a;并行动画组&#xff0c;所有动画一起执行。…

Linux 网络操作命令Telnet

Telnet 尽管 Telnet 已经逐渐被更安全的 SSH 协议所取代&#xff0c;但在某些特定场景下&#xff0c;如对旧系统的维护或教育目的&#xff0c;Telnet 仍然有其使用价值。本文将介绍如何在 Linux 系统中安装 Telnet 客户端&#xff0c;以及如何使用它进行远程登录。 用户使用 t…

Activiti——将绘制的流程图存入act数据库并进行流程推进与状态流转

文章目录 前言流程图入库操作 RepositoryService项目结构数据库连接配置文件入库Java测试代码zip 方式进行流程的批量部署 流程启动 RuntimeService待处理任务查看 TaskService流程状态的扭转查询流程定义信息 RepositoryService查询正在执行的流程实例 RuntimeService已部署流…

Springboot+Vue项目-基于Java+MySQL的在线文档管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

实测14us,Linux-RT实时性能及开发案例分享—基于全志T507-H国产平台

本文带来的是基于全志T507-H&#xff08;硬件平台&#xff1a;创龙科技TLT507-EVM评估板&#xff09;&#xff0c;Linux-RT内核的硬件GPIO输入和输出实时性测试及应用开发案例的分享。本次演示的开发环境如下&#xff1a; Windows开发环境&#xff1a;Windows 7 64bit、Window…

在 Linux 上通过 udev 规则绑定 ttyUSB 设备的相对地址

文章目录 问题描述解决方案1. 分辨当前 USB 设备的绝对地址2. 使用绝对地址查看设备属性3. 使用 udev 规则绑定设备到相对地址3.1. 区分多个不同型号 USB 设备3.2. 区分多个相同型号 USB 设备 问题描述 Linux 系统开机时会随机为连接的 USB 设备随机分配 /dev/ttyUSB* 这样的绝…