进程通信(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循环)。

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

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

相关文章

NLP模型工程化部署

文章目录 一、理论-微服务、测试与GPU1&#xff09;微服务架构2&#xff09;代码测试3&#xff09;GPU使用 二、实践-封装微服务&#xff0c;编写测试用例和脚本&#xff0c;并观察GPU1&#xff09;微服务封装(RestFul和RPC)2&#xff09;测试编写(unit_test\api_test\load_tes…

重生之我在异世界学编程之数据结构与算法:深入队列篇

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 一、概述二、链表节点结构三、队列结构四、基…

在线机考|2024华为实习秋招春招编程题(最新)——第2题_订单取餐顺序_300分(五)

题目内容 肯德基店销售炸鸡、薯条、可乐三种实物,准备三种食物的速度一样,且三种食物同时制作;三种食物同时制作,按订单顺序进行分发食物。现在有N个订单,每个订单用连续三位数组元素表示,数组的元素是对应食物的份数。N最大为100万,每个订单里每份食物最多100万份。请计…

SAP SD信贷管理后台配置(上)

后台系统功能配置 1、定义信贷控制范围 说明&#xff1a; 信贷控制区域是一个控制单元&#xff0c;用于指定和检查合作伙伴的信用额度&#xff1b;信用控制区域可以包含一个或多个公司&#xff0c;但一个公司无法分配给多个信贷控制区域&#xff1b;在信用控制区域内&#x…

​虚幻引擎UE5渲染不够快的解决办法

​虚幻引擎是由Epic Games公司开发的一款功能强大、全球最开放且先进的实时 3D 创作工具&#xff0c;广泛应用于游戏、影视、建筑可视化、虚拟现实等多个领域&#xff01;虚幻引擎UE5如何实现在网上极速渲染呢&#xff1f;本文提供云渲染和云电脑两套方案用于渲染提速&#xff…

算力股开盘大涨,电光科技7连板

12 月 30 日&#xff0c;尽管北证 50 指数半日跌超 3% 再创调整新低&#xff0c;全市场超 4200 股飘绿&#xff0c;但算力概念股却逆势活跃&#xff0c;电光科技实现 7 连板。以下是对这一现象的具体分析&#xff1a; 原因分析 政策利好&#xff1a;上海近日印发《关于人工智能…

kanzi做3d时钟屏保

用kanzi做一个3d屏保 1. blender制作3d数字模型 下载一些好看的字体文件&#xff0c;用blender建模字体模型&#xff0c;导出fbx格式 2. 新建kanzi工程 导入fbx模型&#xff0c;创建节点&#xff0c;时分秒节点&#xff0c;最上面放一个按钮&#xff0c;用来点击 根据喜好…

logback之自定义pattern使用的转换器

目录 &#xff08;1&#xff09;场景介绍 &#xff08;2&#xff09;定义转换器BizCallerConverter &#xff08;3&#xff09;logback配置conversionRule &#xff08;4&#xff09;测试效果 前文《logback之pattern详解以及源码分析》已经介绍了pattern&#xff0c;以及…

QTDemo:串口调试工具

项目简介 本项目通过QT框架设计一款可以在Windows、Linux等平台的跨平台串口助手&#xff0c;串口功能能够满足基本的调试需求。 本项目采用的版本为&#xff1a;QT5.14 visual studio 2022 进行开发。 项目源码&#xff1a;https://github.com/say-Hai/MyCOMDemo 项目页面&am…

Selenium+Java(21):Jenkins发送邮件报错Not sent to the following valid addresses解决方案

问题现象 小月妹妹近期在做RobotFrameWork自动化测试,并且使用Jenkins发送测试邮件的时候,发现报错Not sent to the following valid addresses,明明各个配置项看起来都没有问题,但是一到邮件发送环节,就是发送不出去,而且还不提示太多有用的信息,急的妹妹脸都红了,于…

AI 智能助手对话系统

一个基于 React 和 Tailwind CSS 构建的现代化 AI 对话系统&#xff0c;提供流畅的用户体验和丰富的交互功能。 项目链接&#xff1a;即将开放… 功能特点 &#x1f916; 智能对话&#xff1a;支持与 AI 助手实时对话&#xff0c;流式输出回答&#x1f4c1; 文件处理&#xff…

Design Compiler:两种工作模式(线负载模式和拓扑模式)

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 Design Compiler可以以线负载模式或拓扑模式启动&#xff0c;必须选择其中一个模式。在拓扑模式下还可使用多模式和UPF模式&#xff1a;多模式允许在多种工作…

应急响应练习

文章目录 web1web2 web1 题目要求&#xff1a; 前景需要&#xff1a; 小李在值守的过程中&#xff0c;发现有CPU占用飙升&#xff0c;出于胆子小&#xff0c;就立刻将服务器关机&#xff0c;这是他的服务器系统&#xff0c;请你找出以下内容&#xff0c;并作为通关条件&#…

从零开始构建直播APP美颜功能:直播美颜SDK的开发实践指南

本文将从零开始&#xff0c;详细探讨如何开发一款功能完善的直播美颜SDK&#xff0c;帮助开发者快速集成美颜功能。 一、明确需求与功能设计 开发美颜功能的第一步是明确需求。直播场景中的美颜需求通常包括以下几点&#xff1a; 实时滤镜&#xff1a;提供多种风格的滤镜&am…

.NET周刊【12月第4期 2024-12-22】

国内文章 dotnet 简单使用 ICU 库进行分词和分行 https://www.cnblogs.com/lindexi/p/18622917 本文将和大家介绍如何使用 ICU 库进行文本的分词和分行。 dotnet 简单聊聊 Skia 里的 SKFontMetrics 的各项属性作用 https://www.cnblogs.com/lindexi/p/18621674 本文将和大…

vue3大屏实现;使用使用CSS Grid实现大屏

文章目录 一、效果1.效果2.使用CSS Grid3.插件4.html代码5.index.scss代码 一、效果 1.效果 方案&#xff1a;采用CSS的Grid布局&#xff0c;实现首页大屏模块划分和自适应功能&#xff1b; 布局&#xff1a; 大屏主要内容&#xff0c;高宽比是1920*1080&#xff1b;即16:9的…

基于FISCO BCOS的电子签署系统

概述 本项目致力于构建一个安全、高效且功能完备的电子签署系统&#xff0c;通过整合区块链技术与传统数据库管理&#xff0c;为用户提供了可靠的电子签署解决方案&#xff0c;有效应对传统电子签署系统的数据安全隐患&#xff0c;满足企业和个人在数字化办公环境下对电子文档…

【PCIe 总线及设备入门学习专栏 5 -- PCIE接头引脚定义】

文章目录 PCIe 硬件接口 pin 本文转自&#xff1a;小K 硬件会 2024年09月03日 19:35 北京 PCIe 硬件接口 pin 在使用 PCIe 接口时&#xff0c;可以将 PCIe 金手指插入任何不短于金手指长度的 PCIe 插槽中。比如&#xff1a; x1 的 PCIe 金手指可以插入 x1、x4、x8 和 x16 的…

【开源免费】基于SpringBoot+Vue.JS大型商场应急预案管理系统(JAVA毕业设计)

本文项目编号 T 105 &#xff0c;文末自助获取源码 \color{red}{T105&#xff0c;文末自助获取源码} T105&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识

前言 在iOS开发中Keychain 是一个非常安全的存储系统&#xff0c;用于保存敏感信息&#xff0c;如密码、证书、密钥等。与 NSUserDefaults 或文件系统不同&#xff0c;Keychain 提供了更高的安全性&#xff0c;因为它对数据进行了加密&#xff0c;并且只有经过授权的应用程序才…