《场景化落地:用 Linux 共享内存解决进程间高效数据传输障碍(终篇)》

news/2025/12/7 19:38:52/文章来源:https://www.cnblogs.com/yangykaifa/p/19318686

前引:共享内存是 Linux 进程间通信中效率最高的方式,但 “内存映射原理”“权限配置”“同步机制” 等知识点常让新手望而却步。本文从基础概念拆解入手,先讲清共享内存的工作逻辑,再通过 “创建→挂载→读写→销毁” 完整实操案例,帮你从零掌握核心用法,无论你是 Linux 入门者还是需要夯实基础的开发者,都能快速实现从 “懂概念” 到 “能实操” 的跨越!

目录

【一】共享内存介绍

【二】整体流程与特点

流程:

特点:

【三】使用步骤

(1)申请共享内存

(1)ftok()

(2)shmget()

(2)挂接

(3)去关联

(4)释放共享内存

(5)例如

【四】共享内存效率与内核

【五】信号量与高效


【一】共享内存介绍

共享内存:也属于一种进程通信方式,让多个进程通过访问同一块内存实现通信的方式

【二】整体流程与特点

流程:

总的流程分为以下几步:(已存在的共享内存通过“Key”直接用即可,不用重新申请)

需要先申请共享内存,然后与它建立联系,不想用了就去除关联,最后看情况释放共享内存即可

特点:

(1)共享内存申请之后,如果不主动释放,那它就会等到系统关闭才主动释放——切记

(2)共享内存的通信不会出现阻塞的情况(这是较于两种管道通信最大的区别)

         即:可以同时实现数据写入,A进程不用阻塞等待B进程

(3)通信成功的关键是:读写双方必须约定相同的数据类型和解析规则

         例如:A以字符串写入,B就以字符串读取,如果B是整型读取,就会出现乱码

(4)共享内存的释放:由创建者销毁,且创建者标记“销毁”之后,也会等失去所有挂载连接之后             才会释放这块共享内存。下面是指令版的查看共享内存和销毁:

ipcs  -m        查看所有存在的共享内存

ipcrm  -m  "共享ID"     手动直接销毁该共享内存

【三】使用步骤

(1)申请共享内存

共享内存的申请涉及到两个函数:ftok()shmget()

(1)ftok()

函数原型:

#include 
key_t ftok(const char *pathname, int proj_id);

参数:都是自定义的,系统会根据它们调用算法形成唯一的Key,这个Key是较于操作系统的

         (只要这两个参数相同,就会生成相同的Key->进而找到同一块共享内存)

返回值:

  • 成功:返回一个 key_t 类型的整数(就是生成的 “唯一编号”)
  • 失败:返回 -1(比如路径不存在,或权限不够)

作用:生成 “唯一标识” 较于系统的钥匙Key

(2)shmget()

函数原型:

#include 
int shmget(key_t key, size_t size, int shmflg);

参数:

第一个参数:通过调用ftok()获取的较于操作系统的Key

第二个参数:你理想的共享内存大小(每次最好是4KB,因为“块”以“4KB”为整数标准)

第三个参数:操作标志(权限 + 行为),常用组合:(使用新内存或者旧内存!)

  • IPC_CREAT | 0666:如果 key 对应的共享内存不存在,就新建一个,权限设为 666(所有人可读写,类似文件权限)
  • IPC_EXCL | IPC_CREAT:如果共享内存已存在,就报错(确保一定是新建的,避免误操作已有内存)
  • 单独传 0:只查找已存在的共享内存,不新建

作用:生成 “唯一标识” 较于用户的钥匙ID(其实也算“Key”,只是对于用户层面的)

返回值:

  • 成功:返回一个 “共享内存 ID”(非负整数,后续操作共享内存都用这个 ID
  • 失败:返回 -1(比如权限不够、内存不足、key 不存在且没加 IPC_CREAT)
(2)挂接

挂接:与该共享内存建立联系,比如你想怎么使用,需要用到接口(shmat()

函数原型:(需要强转)

#include 
void *shmat(int shmid, const void *shmaddr, int shmflg);

参数:

第一个参数: “共享内存 ID”

第二个参数:告诉操作系统挂载到共享内存的哪个地方,一般推荐 NULL 参数

第三个参数:挂载权限,一般选择 0 (可读可写)

返回值:

  • 成功:返回共享内存在当前进程地址空间中的实际挂载地址(void*类型,可直接作为指针使用)
  • 失败:-1(可以通过检查errno获取错误原因,如地址冲突、权限不足等)

作用:搭建“窗口”,真正使用共享内存

(3)去关联

即失去与该共享内存的关联,代表不再使用它

函数原型:

#include 
int shmdt(const void *shmaddr);

参数:通过 shmat()挂接该共享内存的指针

返回值:

  • 成功:返回0(表示已成功解除关联)
  • 失败:返回-1(可通过errno查看错误原因,例如shmaddr不是有效的挂载地址、权限不足等)

作用:失去与该共享内存的关联

(4)释放共享内存

函数原型:

#include 
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

参数:

第一个参数: “共享内存 ID”

第二个参数:对共享内存执行的操作(我们暂时学习两个即可)

命令作用
IPC_STAT读取共享内存的状态信息,存储到buf指向的struct shmid_ds结构体中
IPC_RMID标记共享内存为 “待销毁”,当所有进程都卸载后,内核会彻底删除它

第三个参数:

buf是一个指向struct shmid_ds类型的指针,该结构体用于存储或设置共享内存的详细信息

  • cmd=IPC_STAT时:buf用于接收状态(内核会将共享内存的信息写入buf
  • cmd=IPC_RMID时:buf无用,通常传NULL即可

返回值:

  • 成功:返回0(无论执行哪种cmd,成功均返回 0)
  • 失败:返回-1(可通过errno查看错误原因,如权限不足、shmid无效等)

作用:对共享内存执行的操作

(5)例如

我们将Key的获取封装一下:

const char* ptr_ftok="Hello Linux";
const int pid_ftok =1024;

创建共享内存:这里判断省略的是上篇学习的“简易日志”

使用共享内存:这里判断省略的是上篇学习的“简易日志”

【四】共享内存效率与内核

为何是这样?共享内存与文件描述表都是在进程地址空间上的,可以直接跳过文件表访问共享内存

【五】信号量与高效

什么是“互斥”?

当共享内存被两个进程访问时,如果A需要持续写入3秒的数据,但是B进程在二秒的时候就进行了读取,这就导致通信结果不理想,因此为了避免这种情况,任何时刻,只能一个进程(属于执行流)访问该共享资源

什么是“临界资源”?

被多个执行流(进程、线程)都能访问的共享资源,而这些资源,通常是代码、数据

什么是“临界区”?

简单来说:临界区就是执行流正在访问共享资源中的代码数据

因此就算有100行代码在“临界资源”,但是被访问的那5行才叫临界区

什么是“信号量”?

信号量是一个计数器来记录该“临界资源”还可以被多少执行流访问通常执行两个操作:

“P”操作:有执行流访问临界资源,计数-1

“V”操作:该执行流退出访问临界资源,计数器+1

什么是“原子性”?

“原子性”是较于“P”和“V”操作的执行特性:要么不执行,要么执行完

什么是“二元信号量”?

如果信号量的计数器只能是 0(资源无法使用) 或 1(可使用),更像资源的使用状态

效率:信号量(可调用共享资源的执行流数量)+“原子性”——便形成了“互斥”,共享访问达成高效

(注:“信号量”的学习与后面的“信号”无关)

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

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

相关文章

本地AI模型API网址添加到Open WebUI的方法

如下操作如果需要可以付费找我帮助。设置环境变量。setx HF_ENDPOINT "https://hf-mirror.com"、 pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple 根据Open WebUI官方文档…

图像基础核心知识体系

一、 图像基础核心知识体系 1. 像素与分辨率像素:图像的最小单位,一个带有颜色信息的小方点。像素大小通常指图像的总像素数量(宽高),如 19201080(约207万像素)。 分辨率:有两个常见但易混的概念:图像分辨率:…

P14660 你不孤单,我们都在 题解

P14660 你不孤单,我们都在 题解题意 我们有 \(n\) 个朋友,每个朋友有: 当前压力值 \(a_i\) 最大承受值 \(b_i\) 我们可以选择至多一次倾诉活动: 选择任意一些人参加 所有被选中的人的压力值会变成 这些人的压力值的…

Python 潮流周刊#130:Django 6.0 发布了

本周刊由 Python猫 出品,精心筛选国内外的 400+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进 Python 技术,并增长职业和副业的收入。 温馨提…

渗透测试实验一报告

实验目的和要求 实验目的:理解网络扫描、网络侦察的作用;初步掌握搭建网络渗透测试平台;了解并熟悉常用搜索引擎、扫描工具的应用,通过信息收集为下一步渗透工作打下基础。 系统环境:Kali Linux 2、Metasploitabl…

zebra zt610

zebra zt610zebra zt610 Zebra ZT610 是一台工业级条码/标签打印机。它在很多制造、仓储、物流、工控环境里都非常常见 —— 适合你之前提到的 “工厂、产测、物料管理、工控 + MES” 场景。这里是它的主要特点和适用…

基于深度学习的苹果病害检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)

本文介绍了一套基于YOLO系列算法的苹果病害智能检测系统,实现了对叶枯病、锈病等多种病害的自动化识别。系统包含交互式GUI界面、模型训练框架和命令行工具,支持图片、视频及实时检测。技术栈采用Python3.10+PyQt5+S…

代码随想录Day30_贪心4

代码随想录Day30_贪心4用最少数量的箭引爆气球 思路 如果当前数组的左区间没有覆盖前一个数组的右区间,就需要新的箭来击穿。不然就更新新的右区间。 class Solution {static bool cmd(const vector<int>&a…

[论文笔记] Interleaving Static Analysis and LLM Prompting

Introduction 来自 PLDI’24 的 workshop SOAP。一种交错使用 LLM 和静态分析工具的方法,应用于 C 语言编写的系统代码中函数的错误规范推断问题。Background EESI C 语言并没有错误处理。开发者会把错误代码作为返回…

必考

必考1 全排列取消同步流,严禁混用cincout和printg 对于数组printf(“%5d”,ve[i]) 注意记得判断size大小 if (x == n + 1&&ve.size()==n) 不然可能输出无效解 ve.pop_back(); //pop_back不需要传入数 回溯…

一种 DAG 上可达性判定问题的解决方案

1. 问题简述 给定一个有向无环图 \(G=(V,E)\),记 \(n=|V|\),\(m=|E|\)。有 \(q\) 次查询,每次给定两个点 \(a\) 和 \(b\),判断是否存在一条以 \(a\) 为起点,\(b\) 为终点的简单路径。 其中 \(n,m\) 同阶,保证 \(…

网络空间威慑:通过“曝光”手段反制国家级网络间谍活动

在本期“两个极客”节目中,安全研究员The Grugq与政策情报专家Tom Uren深入探讨了是否可能通过“人肉搜索”等干扰措施来威慑国家行为体,使其停止网络间谍活动。内容涉及对特定黑客组织如“迷人小猫”的曝光案例分析…

Gemini 2.5原生音频技术与多模态能力解析

本文详细介绍了Gemini 2.5在音频对话与生成方面的原生技术能力,涵盖实时对话、可控文本转语音、多语言支持以及安全部署等核心技术架构与应用实现。Gemini 2.5的原生音频能力 Gemini自设计之初便是多模态的,原生理解…

实用指南:多种时间序列预测算法的MATLAB实现

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[开源项目] 蜜蜂记账 v2.2 发布:暗黑模式、标签系统、预算管理等 10+ 新功能

项目介绍 蜜蜂记账(BeeCount)是一款开源的跨平台记账应用,使用 Flutter 开发,支持 iOS 和 Android。 项目最大的特点是数据自主可控:支持 iCloud、Supabase、WebDAV、S3 协议等多种云同步方案,用户可以将数据存储…

12 月记录

QOJ14945 QOJ14949 QOJ14711 QOJ14718 QOJ2064 CF2161F QOJ14685 QOJ14025 QOJ14419 https://atcoder.jp/contests/fps-24/tasks/fps_24_r QOJ14426 QOJ5039 P11983 [JOIST 2025] 展览会 3 / Exhibition 3 P13740 [NWE…

嵌入式软件架构--多窗口表明1(后台软件实现)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【09】Word文档处理工具

【09】Word文档处理工具 原理图文档处理工具 原理图库文档处理工具 PCB文档处理工具 PCB库文档处理工具 [0901]Word文档批量转换成PDF.rar 下载链接 [0902]Word文档批量转换成TXT.rar 下载链接

谁在主导“芯片战争”

“芯片,不只是电子元件,更是国家角力的新战场。” 过去三年,全球半导体产业如同棋盘上疾速变动的局面:美国推动芯片立法、拔高工具出口壁垒;台湾、韩国厂商扩张制造版图;中国则在稀土、设备供应链端反击。参与者…

定制化 Live555 实战:按需开发低耗 RTSP 服务器,完美适配 C# 项目 - 源之缘

深耕 Live555 源码核心,具备成熟定制化开发能力,可按需打造高性能 RTSP 服务器。封装的极简 C 接口,4 步即可完成部署,C#/.NET 可无缝集成,大幅降低开发门槛。底层复用 Live555 事件驱动架构,两路高清流并发 CPU…