当前位置: 首页 > news >正文

《场景化落地:用 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(可使用),更像资源的使用状态

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

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

http://www.dtcms.com/a/592509.html

相关文章:

  • 襄阳建设网站首页向网站服务器上传网页文件下载
  • 视频去动态水印软件HitPaw安装和使用教程
  • O2OA(翱途)开发平台 v9.5 前端框架设计|开放 · 安全 · 可控 · 信创优选
  • CMakeList 中 PUBLIC 和 PRIVATE的区别
  • langchain 环境搭建
  • 捷讯官网 网站建设中小型企业网站大全
  • 《算法闯关指南:优选算法--位运算》--36.两个整数之和,37.只出现一次的数字 ||
  • 素材网站开发做流量网站挂广告还能挣钱吗
  • 学习OPC UA,连接OPC UA服务器
  • 从零开始:构建你的第一个MCP服务器
  • 数据结构之二叉树-堆
  • BridgeVLA 对比 pi 0.5 有提升吗
  • 深度学习 :python水下海洋生物识别检测系统 Yolo模型 PyTorch框架 计算机 ✅
  • COM_QueryInterface
  • DeepSeek-OCR全面解析:技术原理、性能优势与实战指南
  • WebKit Insie: WebKit 调试(二)
  • 网站建设需求材料推广网店的途径和方法
  • 排名优化网站沈阳中小企业网站制作
  • 从0到1:兰亭妙微如何用“小程序思维”重构用户体验路径
  • AI重构天猫双11,一场新的效率革命
  • 智慧园区:数字中国的“微缩实验室”如何重构城市未来
  • 新技术如何重构AI营销获客的底层逻辑与竞争格局
  • [论文阅读] AI+ | AI重构工业数字孪生!新一代iDTS破解数据稀缺、智能不足难题,附3大落地案例
  • 京东的一次范围经济尝试,却改变了汽车营销游戏规则
  • 圆柱电池Pack生产线的极性与质量守护:视觉检测系统把好安全关
  • 【大数据技术03】机器学习与算法
  • A模块 系统与网络安全 第四门课 弹性交换网络-6
  • it之家网站源码wordpress门户主体
  • 浏览器访问web服务器经过了哪些过程
  • 时序数据库系列(七):性能监控实战指标收集