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

《场景化落地:用 Linux 共享内存解决进程间高效数据传输问题(终篇)》
前引:共享内存是 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 <sys/ipc.h> key_t ftok(const char *pathname, int proj_id);

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

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

返回值:

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

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

(2)shmget()

函数原型:

#include <sys/shm.h> 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 <sys/shm.h> void *shmat(int shmid, const void *shmaddr, int shmflg);

参数:

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

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

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

返回值:

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

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

(3)去关联

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

函数原型:

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

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

返回值:

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

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

(4)释放共享内存

函数原型:

#include <sys/shm.h> 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(可使用),更像资源的使用状态

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

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

Read more

论文阅读:MiniOneRec

github仓库:https://github.com/AkaliKong/MiniOneRec 技术报告论文:https://arxiv.org/abs/2510.24431 找了一个论文阅读辅助工具:https://www.alphaxiv.org/ 代码 https://github.com/AkaliKong/MiniOneRec SFT在做什么 前置:数据集 代码路径:MiniOneRec/data.py 类Tokenizer:给普通的分词器多包装了一层,可以处理连续的bos/eos的特殊字符串。 SidSFTDataset 多样化的指令 任务:输入用户最近交互过的item列表,预测用户下一个交互的item SidItemFeatDataset sid2title或者title2sid任务 FusionSeqRecDataset 带意图识别的商品推荐 代码 代码入口:MiniOneRec/sft.py 1、

By Ne0inhk

数字电路FPGA原型验证平台搭建快速理解

FPGA原型验证:从零搭建高效数字电路“设计沙盒” 你有没有遇到过这样的场景? 写完几千行Verilog代码,功能仿真跑通了,心里正得意——结果一上板,系统莫名其妙卡死、数据错乱,ILA抓出来的波形像谜语人一样毫无头绪。更糟的是,项目deadline就在下周,流片预算已经批下来了…… 这不是危言耸听,而是每个数字前端工程师都可能踩过的坑。而解决这类问题最有效的手段之一,就是 在FPGA上搭一个原型验证平台 ——它就像一个“硬件模拟器”,让你的设计提前暴露真实世界中的各种边界情况。 今天我们就来拆解这个关键环节:如何快速理解并搭建一套实用的FPGA原型验证环境。不讲空话,只聚焦真正影响开发效率的核心技术点。 为什么仿真不够用了? 在SoC设计日益复杂的今天,纯软件仿真(比如用ModelSim跑RTL)越来越显得力不从心。哪怕是一颗中等规模的处理器子系统,全速仿真一天也未必能跑完一次完整的启动流程。更别说要覆盖所有中断、异常和外设交互路径。 而FPGA的优势在于: 它是真正的并行执行硬件 。你的状态机、总线仲裁、DMA搬运,全部在同一时刻物理运行,速度轻松达到MHz级别——比

By Ne0inhk
【Part 4 XR综合技术分享】第一节|技术上的抉择:三维实时渲染与VR全景视频的共生

【Part 4 XR综合技术分享】第一节|技术上的抉择:三维实时渲染与VR全景视频的共生

《VR 360°全景视频开发》专栏 将带你深入探索从全景视频制作到Unity眼镜端应用开发的全流程技术。专栏内容涵盖安卓原生VR播放器开发、Unity VR视频渲染与手势交互、360°全景视频制作与优化,以及高分辨率视频性能优化等实战技巧。 📝 希望通过这个专栏,帮助更多朋友进入VR 360°全景视频的世界! Part 4|XR综合技术分享 最后一Part了,我将分享一些关于当前常用的XR综合技术,内容涵盖三维实时渲染与全景视频的共生、多模态交互体验的融合,以及AI如何深度赋能XR应用,推动智能化发展。同时畅想通向全感知XR智能沉浸时代的未来,探索如何通过更先进的技术不断提升用户体验。毕竟,360°全景视频仅是XR应用中的冰山一角。 第一节|技术上的抉择:三维实时渲染与VR全景视频的共生 文章目录 * 《VR 360°全景视频开发》专栏 * Part 4|XR综合技术分享 * 第一节|技术上的抉择:三维实时渲染与VR全景视频的共生 * 1、VR内容形态的分化与融合 * 1.1 三维实时渲染的发展 * 1.2

By Ne0inhk
近五年体内微/纳米机器人赋能肿瘤精准治疗综述:以 GBM 为重点

近五年体内微/纳米机器人赋能肿瘤精准治疗综述:以 GBM 为重点

摘要 实体瘤治疗长期受制于递送效率低、肿瘤组织渗透不足以及免疫抑制与耐药等问题。传统纳米药物多依赖被动累积与扩散,难以在肿瘤内部形成均匀有效的药物浓度分布。2021–2025 年,体内微/纳米机器人(包括外场驱动微型机器人、自驱动纳米马达以及生物混合机器人)围绕“运动能力”形成了三条相互收敛的技术路线: 其一,通过磁驱、声驱、光/化学自驱等方式实现运动增强递药与深层渗透,将治疗从“被动到达”推进到“主动进入”; 其二,与免疫治疗深度融合,实现原位免疫唤醒与肿瘤微环境重塑; 其三,针对胶质母细胞瘤(glioblastoma, GBM)等难治肿瘤,研究趋势转向“跨屏障递送(BBB/BBTB)+ 成像/外场闭环操控 + 时空可控释放”的系统工程。 本文围绕“运动—分布—疗效”的因果链条,总结 2021–2025 年代表性研究与关键评价指标,讨论临床转化所需的安全性、

By Ne0inhk