Linux下进程间的通信--共享内存

共享内存概述:

共享内存是进程间通信的一种方式,它允许两个或多个进程共享一个给定的存储区。共享内存是最快的一种IPC形式,因为它允许进程直接对内存进行读写操作,而不需要数据在进程之间复制。

共享内存是进程间通信(IPC)中效率非常高的一种方式,因为它允许多个进程直接访问同一块内存区域,从而避免了数据在进程间复制的开销。这种直接访问内存的方式减少了数据传输的时间,提高了通信效率。

 在 Linux 系统中通过 ipcs -m 查看所有的共享内存

1.创建共享内存:

shmget() 是一个在 Linux 系统上用于创建或获取共享内存段的系统调用

shmget()函数描述:

函数头文件:
#include <sys/ipc.h>
#include <sys/shm.h>函数原型:
int shmget(key_t key, size_t size, int shmflg);函数参数:
key_t key: 这是一个键值,用于标识共享内存段。如果key是IPC_PRIVATE,则创建一个新的共享内存段,并且不与其他任何共享内存段关联。
size_t size: 这是共享内存段的大小,以字节为单位。这个大小必须是一个系统页的整数倍。
int shmflg: 这是一组标志位,用于控制共享内存段的权限和控制选项。
常见的标志位包括:
IPC_CREAT: 如果指定了这个标志,并且key指定的共享内存段不存在,则创建一个新的共享内存段。
IPC_EXCL: 与IPC_CREAT一起使用,如果共享内存段已经存在,则shmget()调用失败。
0666 (八进制): 这是权限掩码,用于设置共享内存段的权限。默认情况下,所有用户都可以读写共享内存段。函数返回值:
成功:返回一个有效的共享内存标识符
失败:返回-1,并设置errno来指示错误
错误原因:
EACCES: 没有权限访问共享内存段。
EEXIST: IPC_CREAT | IPC_EXCL 被设置,但共享内存段已经存在。
EINVAL: size不是系统页大小的整数倍,或者key是无效的。
ENOMEM: 系统内存不足,无法创建新的共享内存段

 扩充知识--系统页大小:

在Linux系统中,"系统页面大小"(也称为"页大小"或"分页大小")是指操作系统用于管理内存的分配单元的大小。这个大小是虚拟内存系统中页表条目的大小,也是内存管理单元(MMU)分页机制的基础。

系统页面大小通常是4KB(即4096字节),但这个值可能会根据不同的体系结构和操作系统的实现而有所不同。例如,在某些64位体系结构上,页面大小可能是8KB或更大。这个大小对于性能优化很重要,因为它决定了内存映射和页表条目的效率。

 示例代码:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <string.h>int main() {size_t size = 1024; // 分配1024字节int shmflg = 0666 | IPC_CREAT; // 设置权限并创建共享内存int shmid = shmget(IPC_PRIVATE, size, shmflg);if (shmid == -1) {fprintf(stderr, "shmget failed: %s\n", strerror(errno));return 1;}printf("Shared memory ID: %d\n", shmid);return 0;
}

 2.附加共享内存:

 shmat() 是一个在 Linux 系统中用于将共享内存段附加到调用进程的地址空间的系统调用。这个函数是共享内存 IPC 机制的一部分,它允许进程访问由 shmget() 创建的共享内存段

shmat()函数描述:

函数头文件:
#include <sys/types.h>
#include <sys/shm.h>函数原型:
void *shmat(int shmid, const void *shmaddr, int shmflg);函数参数:
int shmid: 这是由shmget()函数返回的共享内存段的标识符。
const void *shmaddr: 这是一个可选的指针,指定共享内存段应该被附加到进程地址空间的哪个位置。
如果设置为NULL,系统会自动选择一个合适的地址。int shmflg: 这是一个标志位,用于控制共享内存的附加行为。
可能的标志包括:
SHM_RDONLY: 将共享内存附加为只读。
SHM_RND: 将共享内存附加到一个页面边界地址,这可以提高内存访问的效率。函数返回值:
成功:返回附加的共享内存段的地址
失败:返回(void *) -1,并设置errno以指示错误的原因。
错误原因
EACCES  调用进程没有请求的附加类型所需的权限,
并且在管理IPC命名空间的用户命名空间中没有CAP_IPC_OWNER功能。EIDRM   shmid指向一个已删除的标识符。EINVAL  无效的shmid值,未对齐(即未对齐页面且未指定SHM_RND)或无效的shmaddr值,
或者不能在shmaddr上附加段,或者指定了SHM_REMAP而shmaddr被指定NULL。ENOMEM   无法为描述符或页表分配内存。

 示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>int main() {int shmid;             // 共享内存标识符char *shared_memory;   // 共享内存的指针// 创建一个共享内存段shmid = shmget(IPC_PRIVATE, 1024, 0666 | IPC_CREAT);if (shmid == -1) {perror("shmget");exit(1);}将共享内存附加到其地址空间shared_memory = (char *)shmat(shmid, NULL, 0);if (shared_memory == (char *)(-1)) {perror("shmat");exit(1);}// 写入一些数据到共享内存strcpy(shared_memory, "Hello, World!");return 0;
}

 3.分离共享内存:

当进程不再需要访问共享内存时,可以使用 shmdt 系统调用将其从进程的地址空间中分离

 shmdt()函数描述: 

函数头文件:
#include <sys/types.h>
#include <sys/shm.h>函数原型:
int shmdt(const void *shmaddr);函数参数:
shmaddr: 这是之前通过shmat()函数附加的共享内存段的地址。函数返回值
成功:返回0。
失败:返回-1,并设置errno以指示错误。
错误原因:
EINVAL: 在shmaddr上没有附加共享内存段;或者shmaddr没有在页边界上对齐

4.读写共享内存:

一旦共享内存段被附加到进程的地址空间,进程就可以通过指针直接访问和操作共享内存中的数据。这使得共享内存成为进程间通信(IPC)中非常快速和高效的一种方式。

一旦共享内存段被附加,进程就可以通过指针 shmaddr 读写共享内存。这部分内存就像普通的内存一样使用

示例代码:

void* addr = shmat(shmid,NULL,0);
if(addr == (void*)-1)
{perror("shmat");exit(EXIT_FAILURE);
}
char buf[1024]={0};
memcpy(buf,addr,10);
printf("share memory content:%s\n",buf);
shmdt(addr); //分离共享内存

5.控制共享内存:

在Linux中,共享内存的控制通常通过 shmctl 系统调用来实现。shmctl 函数可以对共享内存段进行多种操作,包括获取共享内存的状态、设置共享内存的状态以及删除共享内存段

shmctl()函数描述:

函数头文件:
#include <sys/ipc.h>
#include <sys/shm.h>函数原型:
int shmctl(int shmid, int cmd, struct shmid_ds *buf);:函数参数:
shmid:共享内存段的标识符,这个标识符是通过shmget()函数创建共享内存段时返回的。
cmd:指定要执行的控制操作。
它可以是以下命令之一:
IPC_STAT:获取共享内存段的状态信息,buf指向的结构会被填充。
IPC_SET:设置共享内存段的属性,buf指向的结构包含了要设置的值。
IPC_RMID:删除共享内存段,只有拥有适当权限的用户(通常是创建者或超级用户)可以执行此操作。
SHM_LOCK:锁定共享内存段,防止其被交换出物理内存。
SHM_UNLOCK:解锁共享内存段,允许其被交换。
IPC_INFO:获取系统范围内共享内存的信息(Linux 特定)。
SHM_INFO:获取系统范围内共享内存的详细信息(Linux 特定)。
SHM_STAT_ANY:获取任何用户的共享内存段的状态信息(Linux 特定,自 Linux 4.17 起支持)。buf:指向shmid_ds结构的指针,该结构用于存储共享内存段的信息或新属性
函数返回值:
成功:0
失败:-1,并设置errno以指示错误原因

 shmid_ds结构体:

示例代码:

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>int main() {int shmid;struct shmid_ds shminfo;shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);// 获取共享内存段的信息if (shmctl(shmid, IPC_STAT, &shminfo) == -1) {perror("shmctl IPC_STAT");return 1;}printf("Size: %ld\n", (long)shminfo.shm_segsz);printf("Last attached: %ld\n", (long)shminfo.shm_nattch);// 删除共享内存段if (shmctl(shmid, IPC_RMID, &shminfo) == -1) {perror("shmctl IPC_RMID");exit(EXIT_FAILURE);}return 0;
}

 结语:

无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力

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

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

相关文章

Linux 中的 Screen 命令详解

目录 前言1. 什么是 Screen 命令2. Screen 命令的主要功能3. Screen 命令的安装4. Screen 的基础使用4.1 启动一个新的 Screen 会话4.2 恢复一个断开的 Screen 会话4.3 退出一个 Screen 会话 5. Screen 命令的常用参数5.1 -S&#xff1a;指定会话名称5.2 -r&#xff1a;恢复会话…

使用SpringCloud构建可伸缩的微服务架构

Spring Cloud是一个用于构建分布式系统的开源框架。它基于Spring Boot构建&#xff0c;并提供了一系列的工具和组件&#xff0c;用于简化开发分布式系统的难度。Spring Cloud可以帮助开发人员快速构建可伸缩的微服务架构。 要使用Spring Cloud构建可伸缩的微服务架构&#xff0…

PCIe进阶之TL:Request Handling Rules

1 Handling of Received TLPs 本节介绍接收到的 TLP 在数据链路层经过完整性验证之后,这些 TLP 在事务处理层时的处理方式。这些规则如下图所示: 接收侧会忽略保留字段。如果 Fmt 字段显示存在至少一个 TLP Prefix : (1)通过检查后续 DWORD 的第一个字节中的 Fmt 字段,…

HTML中直接创建一个“onoff”图形开关包括css+script

1. HTML中直接创建一个“onoff”图形开关 下面是一个完整的HTML文档示例 在HTML中直接创建一个“onoff”图形开关&#xff08;通常指的是一个类似于物理开关的UI组件&#xff0c;可以切换开或关的状态&#xff09;&#xff0c;并不直接支持&#xff0c;因为HTML主要用于内容的…

研究生存指南:必备Zotero插件,让你的文献管理更轻松

在读研阶段&#xff0c;我经常面临大量文献阅读和项目研究的任务。忽略文献整理会导致后续使用时非常不便&#xff0c;查找困难且混乱。导师向我们推荐了 Zotero&#xff0c;经过亲身试用&#xff0c;我发现它非常好用&#xff01;zotero有非常多的插件&#xff0c;能够一个就满…

web学习——VUE

VUE&Element 今日目标&#xff1a; 能够使用VUE中常用指令和插值表达式能够使用VUE生命周期函数 mounted能够进行简单的 Element 页面修改能够完成查询所有功能能够完成添加功能 1&#xff0c;VUE 1.1 概述 接下来我们学习一款前端的框架&#xff0c;就是 VUE。 Vue 是…

kubernetes调度2

1、各种缩写的应用 [rootk8s-master test]# kubectl get rsNAME DESIRED CURRENT READY AGEtest001-64c7957b5c 2 2 2 8m59stest001-698b98bb8f 0 0 0 12m[rootk8s-master test]# kubectl get replicas…

昂科烧录器支持Senasic琻捷电子的蓝牙低功耗芯片SNP746

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中Senasic琻捷电子的蓝牙低功耗芯片SNP746已经被昂科的通用烧录平台AP8000所支持。 SNP746是一款蓝牙低功耗芯片&#xff0c;集成了压力传感器和加速度传感器的测量电路。它是为…

git报错:无法读取远程分支 ‘origin‘ does not appear to be a git repository

问题分析 push上传的时候本地分支和远程分支断开连接 所以重新链接即可 排查问题 1. 查看是否有分支&#xff0c;检查分支是否正确 git branch -v 2. 查看连接是否断开&#xff0c;断开无内容展示 查看远程仓库详细信息&#xff0c;可看到仓库地址 git remote -v 解决…

Linux 信号的产生

1. 概念 在Linux系统中&#xff0c;信号是一种进程间通信的机制&#xff0c;它允许操作系统或其他进程向特定进程发送异步通知。我们可以通过命令 kill -l来查看信号的种类&#xff1a; Linux系统中的信号可以分为两大类&#xff1a;传统信号和实时信号。从上图可以看出它们分…

htop(1) command

文章目录 1.简介2.格式3.选项4.交互式命令5.示例6.小结参考文献 1.简介 htop 是一种交互式、跨平台的基于 ncurses 的进程查看器。 类似于 top&#xff0c;但 htop 允许您垂直和水平滚动&#xff0c;并使用指向设备(鼠标)进行交互。您可以观察系统上运行的所有进程&#xff0…

24年蓝桥杯及攻防世界赛题-MISC-2

11 Railfence fliglifcpooaae_hgggrnee_o{cr} 随波逐流编码工具 分为5栏时,解密结果为:flag{railfence_cipher_gogogo} 12 Caesar rxms{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz} mode1 #12: flag{you_have_learned_caesar_encryption} 随波逐流编码工具 13 base64 base64解…

iOS17找不到developer mode

iOS17找不到开发者模式 developer mode 下载过app之后、弹窗Developer Mode Required之后&#xff0c;这个菜单就出现了&#xff08;之前死活找不到&#xff09;。 背景&#xff1a;用蒲公英分发测试app&#xff0c;有个同事买了新机(iphone 15 pro max)&#xff0c;添加了白名…

ppt一键生成免费版软件有哪些?如何高效生成论文答辩?

答辩经验丰富的人都知道&#xff0c;制作论文答辩ppt是一项既繁琐又耗时的工作。 我们需要从数万字的论文中提炼关键点&#xff0c;梳理内容的逻辑关系&#xff0c;然后进行细致的排版和美化&#xff0c;最后还要进行反复的检查和试讲。整个过程不仅耗费时间&#xff0c;而且需…

硬件工程师笔试面试——变压器

目录 9、变压器 9.1 基础 变压器原理图 变压器实物图 9.1.1 概念 9.1.2 变压器组成结构 9.1.3 变压器原理 9.1.4 变压器的类型 9.1.5 应用领域 9.2 相关问题 9.2.1 变压器的工作原理是什么? 9.2.2 如何选择合适的变压器类型? 9.2.3 变压器在实际应用中,如何进行…

8.1差分边缘检测

基本概念 差分边缘检测是一种图像处理技术&#xff0c;用于检测图像中的边缘。边缘是指图像中灰度值发生显著变化的区域。差分边缘检测通常通过计算图像的梯度来实现&#xff0c;梯度反映了灰度值的变化率。在OpenCV中&#xff0c;可以使用不同的算子来检测不同方向的边缘&…

[docker]入门

本文章主要讲述的是&#xff0c;docker基本实现原理&#xff0c;docker概念的解释&#xff0c;docker的使用场景以及docker打包与部署的应用。 文章中docker所运行的系统&#xff1a;CentOS Linux release 7.9.2009 (Core) 目录 docker是什么&#xff0c;什么时候需要去使用 …

【Git原理与使用】版本管理与分支管理(1)

目录 一、基本操作 1、初识Git 2、Git安装[Linux-centos] 3、Git安装[ Linnx-ubuntu] 4、创建git本地仓库 5、配置Git 6、认识工作区、暂存区、版本库 7、添加文件 8、查看历史提交记录 9、查看.git文件目录结构 10、查看版本库对象的内容 11、小结&#xff08;在本地的.git仓库…

回归预测|基于饥饿游戏搜索优化随机森林的数据回归预测Matlab程序HGS-RF 多特征输入单输出 高引用先用先创新

回归预测|基于饥饿游戏搜索优化随机森林的数据回归预测Matlab程序HGS-RF 多特征输入单输出 高引用先用先创新 文章目录 一、基本原理1. 饥饿游戏搜索优化算法&#xff08;HGS&#xff09;简介2. 随机森林&#xff08;RF&#xff09;简介3. HGS-RF回归预测流程1. 初始化2. 随机森…

基于SpringBoot+Vue+MySQL的在线宠物用品商城销售系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着人们生活质量的提升和宠物经济的蓬勃发展&#xff0c;宠物已成为众多家庭不可或缺的一员。宠物市场的需求日益增长&#xff0c;涵盖了食品、用品、医疗、美容等多个领域。基于SpringBootVueMySQL的在线宠物用品商城销售系统…