进程通信(11)System V共享内存区

System V共享内存区

创建或获取共享内存标识符:使用shmget系统调用,根据给定的关键字(key)、大小和标志创建一个新的共享内存段或获取一个已存在的共享内存段的标识符(ID)。这个关键字可以是任意值或者是通过ftok函数从文件路径和一个项目ID生成的。

将共享内存段附加到进程地址空间:使用shmat系统调用将由shmget返回的共享内存段ID所标识的共享内存段附加到调用进程的地址空间。这使得进程可以直接通过指针访问共享内存内容。

对于每个共享内存段,内核维护一个shmid_ds结构体,用于存储关于该段的信息。

struct ipc_perm shm_perm:包含共享内存段的权限和所有者信息。
size_t shm_segsz:共享内存段的大小(以字节为单位)。
pid_t shm_lpid:最后执行操作的进程ID。
pid_t shm_cpid:创建共享内存段的进程ID。
shmatt_t shm_nattch:当前附着到此共享内存段的进程数量。
shmatt_t shm_cnattch:核心中附着的进程数量(这个字段在某些实现中可能不可用)。
time_t shm_atime:最后一次附着时间。
time_t shm_dtime:最后一次分离时间。
time_t shm_ctime:本结构最后一次改变的时间。

ipc_perm结构包含了类似文件权限的信息,定义了哪些用户和组可以对共享内存段进行读取、写入和控制操作。shm_cnattch字段并不在所有的操作系统版本中都存在;它可能被废弃或者从未实现过。

shmatt_t 和 time_t 是类型定义,前者用于计数器,后者用于表示时间。

操作共享内存区:除了shmget和shmat之外,还有其他几个函数用来管理和控制共享内存段。

shmdt:从调用进程的地址空间中分离共享内存段。shmctl:用于执行各种控制操作,例如修改权限、获取或设置shmid_ds结构中的信息,以及销毁共享内存段。

shmat 函数用于将由 shmget 创建或获取的共享内存段附加到调用进程的地址空间中。

#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int flag);

返回值:如果成功,函数返回指向共享内存段起始地址的指针;如果出错,则返回 (void *)-1。

shmid:这是通过 shmget 调用获得的共享内存标识符。shmaddr:指定共享内存段应该被附加到的地址。如果为 NULL(推荐做法),则操作系统选择合适的地址进行附加。

如果是一个非空指针,那么根据 flag 参数中的标志来决定如何处理这个地址。

flag:这是一个位掩码,用来指定附加时的行为。

SHM_RND:当设置了此标志并且 shmaddr 是一个非空指针时,共享内存段会附加到 shmaddr 向下舍入到最近的 SHMLBA 边界处。SHMLBA 代表低端边界地址(Lower Boundary Address),它通常是一个页面大小。SHM_RDONLY:设置此标志后,进程只能以只读方式访问共享内存段。

地址选择规则:当 shmaddr 是NULL 时,系统自动选择一个适当的地址。这种方法具有最好的可移植性,并且是推荐的做法。当shmaddr 不是 NULL 时,附加行为取决于是否设置了 SHM_RND 标志。

如果没有设置 SHM_RND,则直接使用 shmaddr 指定的地址作为附加位置。如果设置了 SHM_RND,则使用 shmaddr 向下舍入到 SHMLBA 的地址作为附加位置。

权限

默认情况下,只要调用进程对共享内存段有读写权限,它就可以在附加之后对该内存段进行读写操作。但是,如果在 flag 中指定了 SHM_RDONLY,那么该进程就只能以只读模式访问共享内存段。

使用建议

(1)除非有特殊需求,否则应尽量让操作系统选择附加地址,即令 shmaddr 为 NULL。

(2)在多进程环境中,确保所有进程都正确地同步它们对共享内存的操作,以避免竞态条件和其他并发问题。

shmdt 函数

shmdt 函数用于从调用进程的地址空间中分离(断接)一个之前通过 shmat 连接的共享内存段,删除共享内存段本身;它只是解除了该进程对共享内存段的访问。

#include <sys/shm.h>
int shmdt(const void *shmaddr);

返回值:如果成功,函数返回 0;如果出错,则返回 -1。

shmaddr:这是由 shmat 返回的指向共享内存段起始地址的指针。如果传递给 shmdt 的地址不是一个有效的共享内存段地址,则会引发错误。

注意事项

当一个进程终止时,它当前附接的所有共享内存区都会自动断开连接。

shmdt 不会删除共享内存段;要删除共享内存段,需要使用 shmctl 函数并指定 IPC_RMID 命令。

shmctl 函数

shmctl 提供了对一个共享内存段进行多种控制操作的能力。它可以用来获取或设置与共享内存段相关的参数,也可以用来删除共享内存段。

#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

返回值:如果成功,函数返回 0;如果出错,则返回 -1。

shmid:这是通过 shmget 获得的共享内存标识符。

cmd:这个参数指定了要执行的操作命令。

IPC_RMID:立即从系统中移除由 shmid 标识的共享内存段,并减少其引用计数。如果引用计数降为零,那么共享内存段将被彻底删除。

IPC_SET:设置共享内存段的权限和其他属性。具体来说,它会更新 shmid_ds 结构中的 shm_perm.uid、shm_perm.gid 和 shm_perm.mode 成员,这些值来自于 buf 指向的结构体。此外,还会用当前时间更新 shm_ctime。

IPC_STAT:获取指定共享内存段的当前状态信息,并将其存储在 buf 指向的 shmid_ds 结构中。

buf:这是一个指向 shmid_ds 结构的指针,用于传递或接收共享内存段的信息。

shmget 程序

此程序用于创建一个指定大小的System V共享内存区。

#include "unpipc.h" // 假设包含了必要的头文件
int main(int argc, char **argv) {int c, id, oflag = SVSHM_MODE | IPC_CREAT;size_t length;while ((c = getopt(argc, argv, "e")) != -1) {switch (c) {case 'e':oflag |= IPC_EXCL;break;}}if (optind != argc - 2)err_quit("usage: shmget [-e] <pathname> <length>");length = atoi(argv[optind + 1]);key_t key = ftok(argv[optind], 0);id = shmget(key, length, oflag);if (id == -1)err_sys("shmget error");void *ptr = shmat(id, NULL, 0);if (ptr == (void *)-1)err_sys("shmat error");exit(0);
}

功能描述:

使用命令行参数提供的路径名(由 ftok 转换为键值)和长度创建一个新的共享内存段。

如果指定了 -e 选项,并且该内存区已经存在,则会出错。

将新创建或已存在的共享内存段附接到当前进程地址空间中。

shmrmid 程序

此程序用于删除一个指定的System V共享内存区。

#include "unpipc.h"
int main(int argc, char **argv) {if (argc != 2)err_quit("usage: shmrmid <pathname>");key_t key = ftok(argv[1], 0);int id = shmget(key, 0, SVSHM_MODE);if (id == -1)err_sys("shmget error");if (shmctl(id, IPC_RMID, NULL) == -1)err_sys("shmctl(IPC_RMID) error");exit(0);
}

使用命令行参数提供的路径名获取共享内存段ID,并使用 IPC_RMID 命令删除它。

shmwrite 程序

此程序向一个指定的共享内存区写入一个模式(从0到255循环)。

#include "unpipc.h"
int main(int argc, char **argv) {if (argc != 2)err_quit("usage: shmwrite <pathname>");key_t key = ftok(argv[1], 0);int id = shmget(key, 0, SVSHM_MODE);if (id == -1)err_sys("shmget error");unsigned char *ptr = (unsigned char *)shmat(id, NULL, 0);if (ptr == (void *)-1)err_sys("shmat error");struct shmid_ds buff;if (shmctl(id, IPC_STAT, &buff) == -1)err_sys("shmctl(IPC_STAT) error");for (size_t i = 0; i < buff.shm_segsz; i++)ptr[i] = i % 256;exit(0);
}

功能描述:

打开指定的共享内存区并将其附接到当前进程的地址空间。

写入从0到255循环的数据模式到共享内存区。

shmread 程序

此程序用于验证由 shmwrite 写入的数据模式是否正确。

#include "unpipc.h"
int main(int argc, char **argv) {if (argc != 2)err_quit("usage: shmread <pathname>");key_t key = ftok(argv[1], 0);int id = shmget(key, 0, SVSHM_MODE);if (id == -1)err_sys("shmget error");unsigned char *ptr = (unsigned char *)shmat(id, NULL, 0);if (ptr == (void *)-1)err_sys("shmat error");struct shmid_ds buff;if (shmctl(id, IPC_STAT, &buff) == -1)err_sys("shmctl(IPC_STAT) error");for (size_t i = 0; i < buff.shm_segsz; i++) {unsigned char c = ptr[i];if (c != (i % 256))err_ret("ptr[%zu] = %d", i, c);}exit(0);
}

打开指定的共享内存区并将其附接到当前进程的地址空间。验证共享内存区中的数据模式是否与预期相符(即从0到255循环)。

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

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

相关文章

手机发烫怎么解决?

在当今这个智能手机不离手的时代&#xff0c;手机发烫成了不少人头疼的问题。手机发烫不仅影响使用手感&#xff0c;长期过热还可能损害手机硬件、缩短电池寿命&#xff0c;甚至引发安全隐患。不过别担心&#xff0c;下面这些方法能帮你有效给手机 “降温”。 一、使用习惯方面…

BUUCTF Pwn ciscn_2019_es_2 WP

1.下载 checksec 用IDA32打开 定位main函数 发现了个假的后门函数&#xff1a; 看看vul函数&#xff1a; 使用read读取 想到栈溢出 但是只有48个 只能覆盖EBP和返回地址 长度不够构造 所以使用栈迁移&#xff1a; 栈迁移需要用到leave ret 使用ROPgadget找地址&#xff1a; …

IEDA 使用auto Dev编码助手配置Deep Seek V3

文章目录 API Key的申请和创建auto Dev的下载auto Dev的安装Deep seek V3的连接配置和注意事项错误解决&#xff1a;You LLM server Key is empty API Key的申请和创建 登陆Deep Seek开放平台&#xff0c;创建API Key 并复制 auto Dev的下载 auto Dev项目地址&#xff0c;发…

vue3学习笔记(6)-生命周期、hooks

1.生命周期 <template><div><div>{{ a }}</div><div click"test"></div></div> </template> <script setup lang"ts" name"hi"> import { ref, onBeforeMount, onMounted, onBeforeUpdat…

#端云一体化开发# #HarmonyOS Next#《说书人》鸿蒙原生基于角色的对话式文本编辑开发方案

1、写在前面 过去的一百年里&#xff0c;在“编程”的这个行业诞生之初&#xff0c;人们采用面向过程的方式进行开发&#xff0c;但是&#xff0c;伴随着程序规模的日益增大&#xff0c;程序的复杂度也随之增加&#xff0c;使用结构化编程方法来管理复杂的程序逻辑变得越来越困…

【ELK】ES单节点升级为集群模式--太细了!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言准备工作1. 查看现状【单节点】2. 原节点改集群模式3. 改es配置文件&#xff0c;增加集群相关配置项4. *改docker映射的端口* 启动新节点5. docker-compose起一…

Python跨年烟花

目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…

未来网络技术的新征程:5G、物联网与边缘计算(10/10)

一、5G 网络&#xff1a;引领未来通信新潮流 &#xff08;一&#xff09;5G 网络的特点 高速率&#xff1a;5G 依托良好技术架构&#xff0c;提供更高的网络速度&#xff0c;峰值要求不低于 20Gb/s&#xff0c;下载速度最高达 10Gbps。相比 4G 网络&#xff0c;5G 的基站速度…

艾体宝方案丨全面提升API安全:AccuKnox 接口漏洞预防与修复

一、API 安全&#xff1a;现代企业的必修课 在现代技术生态中&#xff0c;应用程序编程接口&#xff08;API&#xff09;扮演着不可或缺的角色。从数据共享到跨平台集成&#xff0c;API 成为连接企业系统与外部服务的桥梁。然而&#xff0c;伴随云计算的普及与微服务架构的流行…

# 【鸿蒙开发】多线程之Worker的使用

【鸿蒙开发】多线程之Worker的使用 文章目录 【鸿蒙开发】多线程之Worker的使用前言一、Worker的介绍二、注意事项三、Worker使用示例1.新建一个Worker2.主线程使用Worker3.子线程Worker的使用 四、效果展示 前言 本文主要介绍了多线程的方法之一&#xff0c;使用Worker开启多…

leetcode 面试经典 150 题:矩阵置零

链接矩阵置零题序号73题型二维数组解题方法标记数组法难度中等熟练度✅✅✅✅ 题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1]…

适用于项目经理的跨团队协作实践:Atlassian Jira与Confluence集成

适用于项目经理的跨团队协作实践&#xff1a;Atlassian Jira与Confluence集成 现代项目经理的核心职责是提供可视性、保持团队一致&#xff0c;并确保团队拥有交付出色工作所需的资源。在过去几年中&#xff0c;由于分布式团队的需求不断增加&#xff0c;项目经理这一角色已迅速…

MySQL官网驱动下载(jar包驱动和ODBC驱动)【详细教程】

1.打开MySQL的官网&#xff0c;选择下载(Download) MySQL[这里是图片001]https://www.mysql.com/cn/ 2.往下划点击MySQL Community(GPL)Downloads 3.要下载MySQL的jar包的选择Connector/J 4.进入后&#xff0c;根据自己的需求选择相应的版本 5.下载完成后&#xff0c;进行解压…

WPF 绘制过顶点的圆滑曲线 (样条,贝塞尔)

在一个WPF项目中要用到样条曲线&#xff0c;必须过顶点&#xff0c;圆滑后还不能太走样&#xff0c;捣鼓一番&#xff0c;发现里面颇有玄机&#xff0c;于是把我多方抄来改造的方法发出来&#xff0c;方便新手&#xff1a; 如上图&#xff0c;看代码吧&#xff1a; ----------…

北京某新能源汽车生产及办公网络综合监控项目

北京某新能源汽车是某世界500强汽车集团旗下的新能源公司&#xff0c;也是国内首个获得新能源汽车生产资质、首家进行混合所有制改造、首批践行国有控股企业员工持股的新能源汽车企业&#xff0c;其主营业务包括纯电动乘用车研发设计、生产制造与销售服务。 项目现状 在企业全…

【阅读笔记】《基于区间梯度的联合双边滤波图像纹理去除方法》

一、联合双边滤波背景 联合双边滤波&#xff08;Joint Bilateral Filter, JBF&#xff09;是一种图像处理技术&#xff0c;它在传统的双边滤波&#xff08;Bilateral Filter, BF&#xff09;基础上进行了改进&#xff0c;通过引入一个引导图&#xff08;guidance image&#x…

VIM: Vision Mamba基于双向状态空间模型的高效视觉表示学习

这篇文章的主要内容可以概括如下&#xff1a; 背景与动机&#xff1a; 近年来&#xff0c;状态空间模型&#xff08;SSM&#xff09;在长序列建模中展现出巨大潜力&#xff0c;尤其是Mamba模型在硬件感知设计上的高效性。 然而&#xff0c;现有的SSM模型在处理视觉数据时面临…

京存SAN助力电子病历建设

引言 随着信息技术的快速发展&#xff0c;电子病历系统(EMR)已成为现代医疗的重要组成部分。电子病历不仅能够提高医疗服务的效率和质量&#xff0c;还能更好地保护患者的隐私和数据安全。作为国内领先的存储解决方案提供商&#xff0c;京存存储凭借其卓越的技术实力和丰富的实…

python利用selenium实现大麦网抢票

大麦网&#xff08;damai.cn&#xff09;是中国领先的现场娱乐票务平台&#xff0c;涵盖演唱会、音乐会、话剧、歌剧、体育赛事等多种门票销售。由于其平台上经常会有热门演出&#xff0c;抢票成为许多用户关注的焦点。然而&#xff0c;由于票务资源的有限性&#xff0c;以及大…

【疑难杂症】 HarmonyOS NEXT中Axios库的响应拦截器无法拦截424状态码怎么办?

今天在开发一个HarmonyOS NEXT的应用的时候&#xff0c;发现http接口如果返回的状态码是424时&#xff0c;我在axios中定义的拦截器失效了。直接走到了业务调用的catch中。 问题表现&#xff1a; 我的拦截器代码如下&#xff1a; 解决办法&#xff1a; 先说解决办法&#xff…