【Linux】进程间通信 -- 信号量

news2024/11/25 20:37:48

  • 概念引入
  • 为什么要信号量?
  • 信号量操作接口
    • 1.申请信号量semget
    • 2.控制信号量semctl
    • 3.处理信号量semop
  • IPC资源的组织方式

概念引入

信号量是什么?
本质是一个计数器,通常用来表示公共资源中,资源数量多少的问题

公共资源:能被多个进程同时可以访问的资源

访问没有保护的公共资源:数据不一致问题(比如我想写abc123,但是我123还没有写入,就读取了abc,可能数据分开会导致数据无意义)

为什么要让不同的进程看到同一份资源呢?

因为我想通信,进程间实现协同。但是进程具有独立性,没有办法让两个进程直接通信,为了解决这种问题,解决办法就是让进程看到同一份资源,但是因为提出了这个方法,同时也引入了新的问题:数据不一致

我们将保护起来的公共资源称为:临界资源(大部分资源是独立的)

资源包括内存、文件、网络等,资源存在的意义就是要被使用,如何被进程使用呢?
一定是该进程有对应的代码来访问这部分临界资源(有临界区就有非临界区)

多进程在进行进程间通信时本质是要看到一份公共的资源,这部分公共资源在未来如果被保护起来,那么这部分公共资源我们就称其为临界资源,而访问该临界资源中我们自己的那部分代码我们叫做临界区,不访问临界资源那部分代码的我们叫做非临界区

如何保护资源:互斥与同步
原子性:要么不做,要做就做完,只有两种状态(不会被线程调度机制打断的操作)

为什么要信号量?

举例认识:比如我们看电影,我们不是只要坐在一个座位上,那么这个座位就属于你了,而是你要去买票,然后给你分配一个座位,这个座位才属于你,不管你去不去,你只要买票了,那么这个座位始终都会留给你,这种电影买票的本质:对放映厅中的座位进行预定机制。我们想要某种资源的时候也可以进行预定。

共享资源的使用:作为一个整体使用、划分为一个一个的子资源使用
我们想让不同的进程同时访问一份资源的不同区域,这样我们某种程度上能实现并发

假如我们将一份共享资源(电影院)分成几份,进程(人),访问共享资源的子部分(电影的座位),我们不能直接去访问这些资源(不能不买票随便坐),信号量(电影票),每个进程先申请信号量,如果申请成功了,就相当于预定这部分资源(买到票有座位),申请失败就不允许访问这部分资源(没买票到不允许看电影)。这种申请信号量方式以达到保护共享资源,约束其他进程的目的。信号量就是计数器(电影票是有限的),申请一个就少一个。

sem = 20;//定义信号量总数

sem--;  //预定资源

//访问公共资源

sem++;  //释放资源

PV操作:P → 预定资源 V → 释放资源

所有的进程在访问公共资源之前,都必须先申请sem信号量→必须先申请sem信号量的前提,是所有进程必须先得看到同一个信号量→信号量本身就是公共资源→信号量是不是也要保证自己的安全呢?- -,++→信号量必须保证自身操作的安全性,- -,++操作是原子! !

如果一个信号量初始值为1:二元信号量–互斥功能

思考:有没有可能两个进程都申请信号量成功了却访问同一个资源?
有的,申请信号量成功只能表明这个资源一定有部分是留给你访问的,但具体是哪一部分还需要确认。这部分的工作一般是由程序员来指定的


信号量操作接口

1.申请信号量semget

在这里插入图片描述
函数原型:

int semget(key_t key, int nsems, int semflg);

函数参数:

  1. key:一个用于标识信号量集的键值,它必须是一个非零的整数。通常使用 ftok 函数来生成键值。
  2. nsems:信号量集中包含的信号量的数量。这个参数必须是一个大于零的整数。
  3. semflg:一个标志参数,用于指定信号量集的创建和访问权限。常见的标志包括:
    IPC_CREAT:如果指定的 key 值对应的信号量集不存在,则创建它。
    IPC_EXCL:如果同时指定了 IPC_CREAT 和 IPC_EXCL 标志,而对应的信号量集已经存在,则会出现错误。
    0666:指定新创建的信号量集的权限。这个参数使用八进制表示,表示该信号量集可以被所有用户读写。

函数返回值:
semget 函数的返回值是一个信号量集的标识符,也称为“信号量集描述符”。它是一个非负整数,可以用于后续的信号量操作函数中。

2.控制信号量semctl

在这里插入图片描述
函数原型:

int semctl(int semid, int semnum, int cmd, ...);

函数参数:

  1. semid:一个信号量集的标识符,它是由 semget 函数返回的。

  2. semnum:要操作的信号量在信号量集中的编号,从 0 开始计数。

  3. cmd:用于指定要执行的操作,常见的操作包括:
    GETVAL:获取指定信号量的当前值。
    SETVAL:设置指定信号量的值。
    IPC_RMID:删除指定的信号量集。
    IPC_STAT:获取指定信号量集的状态信息。
    IPC_SET:设置指定信号量集的状态信息。

  4. ... :可选参数,用于给 SETVAL 命令指定要设置的值。

函数返回值根据不同的命令而异:

  • 对于 GETVAL 命令,返回指定信号量的当前值。
  • 对于 SETVAL 命令,返回 0 表示操作成功,-1 表示操作失败。
  • 对于 IPC_RMID、IPC_STAT 和 IPC_SET 命令,返回 0 表示操作成功,-1 表示操作失败。

3.处理信号量semop

在这里插入图片描述

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

函数参数:

  1. semid:一个信号量集的标识符,它是由 semget 函数返回的。
  2. sops:一个指向 sembuf 结构体数组的指针,每个结构体描述一个操作。sembuf 结构体定义如下:
struct sembuf {
    unsigned short sem_num;  // 操作的信号量在信号量集中的编号
    short sem_op;            // 操作的值
    short sem_flg;           // 操作的标志
};
- `sem_num`:要操作的信号量在信号量集中的编号,从 0 开始计数。

- `sem_op`:要执行的操作,可以是一个正数、负数或零。

  - 如果 `sem_op` 是一个正数,表示对应的信号量的值将增加 `sem_op`。

  - 如果 `sem_op` 是一个负数,表示对应的信号量的值将减少 `sem_op`。

  - 如果 `sem_op` 是零,表示对应的信号量的值不变。

- `sem_flg`:操作的标志,包括:

  - `SEM_UNDO`:表示在进程异常终止时,内核将撤销该进程所做的所有操作。

  - `IPC_NOWAIT`:表示如果无法立即执行相应的操作,则立即返回。
  1. nsops:sops 数组中元素的数量。

函数返回值:
表示是否操作成功,如果成功则返回 0,如果失败则返回 -1。

IPC资源的组织方式

共享内存、消息队列、信号量它们的接口相似度很高,比如获取与删除

且它们开始都是定义:

struct ipc_perm {
    key_t          __key;    /* Key supplied to shmget(2) */
    uid_t          uid;      /* Effective UID of owner */
    gid_t          gid;      /* Effective GID of owner */
    uid_t          cuid;     /* Effective UID of creator */
    gid_t          cgid;     /* Effective GID of creator */
    unsigned short mode;     /* Permissions + SHM_DEST and
                                SHM_LOCKED flags */
    unsigned short __seq;    /* Sequence number */
};

在这里插入图片描述
对其进行操作:

(struct shmid_ds*)perms[0]->其他的属性

struct shmid_di myshm;
perms[0] = &myshm.shm_perm;

struct msqid_ds mymsg;
perms[1] = &mymsg.msg_perm;

结构体的第一个成员的地址,在数字上和结构体对象本身的地址数字是相等的,我们就可以通过结构体的地址,强转struct shmid_ds*来使用其里面的其他属性,如上述伪代码。


如有错误或者不清楚的地方欢迎私信或者评论指出🚀🚀

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

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

相关文章

BUUCTF-JustEscape

目录 信息搜集 bypass 黑名单机制 绕过沙盒执行系统命令 总结 这是一道 Node.js 沙盒逃逸的题目&#xff0c;在此记录一些技巧。 信息搜集 进入题目环境&#xff1a; 直接给出了一个可执行任意代码的入口 /run.php?code<code>&#xff0c;直接复制第二个 demo 的路…

常见安装工具以及命令(工作常用)

dockermongodbnginxredis 1.docker 启动2.docker 安装 MongoDB3.启动nginx4.redis配置&#xff0b;安装4.1 Redis的启动和停止4.2 后台启动方式 1.docker 启动 安装docker # 1.安装gcc和g yum -y install gcc yum -y install gcc-c # 2. 安装需要的软件包 yum install -y yum…

DNS详细解析

文章目录 DNS是什么以及作用下载DNS服务named.conf DNS查询DNS缓存机制解析过程递归查询和迭代查询 DNS服务器的类型DNS域名DNS服务器的类型搭建dns服务器缓存域名服务器主域名服务器从域名服务器排错反向解析 CDN介绍 DNS转发介绍配置 DNS劫持 DNS 是什么以及作用 DNS&#…

WEB:Web_php_include(多解)

背景知识 文件包含 file://协议 php://协议 data://协议 了解strstr函数 题目 <?php show_source(__FILE__); echo $_GET[hello]; /*可以构造payload*/ $page$_GET[page]; while (strstr($page, "php://")) { /*strstr()函数*/$pagestr_replace("php://&q…

JavaSwing+MySQL的购物系统项目

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88052733?spm1001.2014.3001.5503 JDK1.8 MySQL5.7 功能&#xff1a;管理员与用户两个角色&#xff0c;管理员可以对商品进行增删改查处理&#xff0c;用户可以浏览查找商品&#xff0c;注…

CROSSROADS1靶机复盘

CROSSROADS1靶机复盘 这个靶机学会了三个工具enum4linux&#xff0c;smbclient&#xff0c;stegoveritas。枚举服务器可能开启的一些资源&#xff0c;smb扫描工具&#xff0c;还有一个隐写术的工具。 靶场下载地址&#xff1a;https://download.vulnhub.com/crossroads/cross…

4.5.tensorRT基础(1)-onnx文件及其结构的学习,编辑修改onnx

目录 前言1. onnx1.1 导出onnx1.2 读取onnx1.3 创建onnx1.4 编辑onnx1.5 onnx总结1.6 本节知识点 2. 补充知识2.1 Protobuf2.1.1 Protobuf简介2.1.2 基本使用流程 总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记…

【Nacos】适配PostgreSQL数据库

目录 本文环境介绍修改application.properties下载PostgreSQL扩展插件初始化PostgreSQL启动测试 本文环境介绍 组件依赖版本Nacos2.2.3OpenJDK17.0.2PostgreSQL Server15 修改application.properties ### Deprecated configuration property, it is recommended to use spri…

手搓一台简单的网络损伤仪——弱网测试

1、介绍 支持对链路带宽、传输时延、丢包率和无码率的手动设置&#xff1b; 1.1、网络损伤仪在使用时&#xff0c;网络拓扑连接 1.2、网络损伤仪管理页面展示 2、使用的设备及相关技术栈 一台Intel 赛扬 J1900的迷你主机【拥有4个千兆网口】&#xff1b;ubuntu-18.04.5-live…

(数组与矩阵) 剑指 Offer 04. 二维数组中的查找 ——【Leetcode每日一题】

❓ 剑指 Offer 04. 二维数组中的查找 难度&#xff1a;中等 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#x…

使用Stable Diffusion和PyTorch创建艺术二维码

大家好&#xff0c;本文将介绍如何利用Stable Diffusion和PyTorch的能力来创建AI生成的QR码艺术。通过将这些技术相结合&#xff0c;可以生成独特的、具有视觉吸引力的艺术作品&#xff0c;其中包含QR码&#xff0c;为艺术作品增添了互动元素。 Stable Diffusion和PyTorch 稳…

赢得CSDN铁粉的秘诀!(记录写作三个月的点点滴滴)

在CSDN上写博客已经三个多月了&#xff0c;从开始的陌生到渐渐熟悉CSDN网站的每个角落&#xff0c;猛然发现还有这么一个活动&#xff0c;想了想还是写一篇博客吧&#xff0c;不仅是参加活动&#xff0c;也是记录这一路慢慢探索的过程。 1.CSDN铁粉介绍及说明 CSDN 是为中国 I…

C++进阶:map和set

map和set STL容器分为序列式容器和关联式容器。 序列式容器vector、list等底层为线性数据结构&#xff0c;数据元素之间没有联系&#xff0c;一般用来存储数据。关联式容器map、set等底层采用平衡搜索树&#xff0c;存储的是<key/value>式的键值对&#xff0c;数据检索效…

NOSQL简单实战

目录 实战一&#xff1a; 1、 string类型数据的命令操作&#xff1a; &#xff08;1&#xff09; 设置键值&#xff1a; &#xff08;2&#xff09; 读取键值&#xff1a; &#xff08;3&#xff09; 数值类型自增1&#xff1a; &#xff08;4&#xff09; 数值类型自减1&…

基于html2canvas和jspdf将document DOM节点转换为图片生成PDF文件,并下载到本地

这里要用到html2canvas将document DOM节点转换为图片&#xff0c;并下载到本地_你挚爱的强哥的博客-CSDN博客前端用原生js编辑文件内容→创建生成文件(格式可以自定义)→下载文件_你挚爱的强哥的博客-CSDN博客。会自动创建一个html文件。https://blog.csdn.net/qq_37860634/art…

业务中添加历史版本事务并发处理

业务背景&#xff1a;项目中包含历史版本的管理&#xff0c;每次保存历史版本都添加一条新的记录到数据库&#xff0c;且版本号加1。保存版本的时候1.要先查询历史版本数据表&#xff0c;获取当前最新的版本号&#xff1b;2.最新的版本号加1&#xff0c;插入数据历史版本记录表…

dp算法 力扣174地下城游戏

在学习编程时&#xff0c;算法是一道硬菜&#xff0c;而dp作为算法的一份子&#xff0c;它的地位在编程界举足轻重。 174. 地下城游戏 - 力扣&#xff08;LeetCode&#xff09; 本文是Java代码哦~ 一、题目详情 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地…

Vue列表渲染(v-for)以及key的作用与原理

索引值的两种写法&#xff1a; <!--index遍历时的默认索引值--> <ul><li v-for"(p,index) in persons":key"index">{{p.name}}--{{p.age}}</li></ul> 代码&#xff1a; v-for"p in persons" :key"p.id&quo…

【多维数组对象拍平处理为一维数组】

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

深谋远“绿”,数据中心未来之路在何方?

数据中心未来演进方向是什么&#xff1f; 在中国绿色算力大会-华为数据中心平行会议上&#xff0c;业界愈发形成共识&#xff1a;即在双碳目标的大背景下&#xff0c;数据中心走向绿色低碳化、智能化。 去年初&#xff0c;东数西算工程正式启动建设&#xff0c;标志着我国数据…