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

《Linux系统编程篇》共享内存(Linux 进程间通信(IPC))——基础篇

文章目录

  • 引言
  • 什么是共享内存
    • System V 共享内存 API 引入
      • 1. `shmget`
      • 2. `shmat`
      • 3. `shmdt`
      • 4. `shmctl`
      • 5. 结构体 `shmid_ds`
    • 开始实操
    • 注意
  • 结束

今天的你有没有前进一小步呢

——家驹(StrangeHead)

引言

那么共享内存,我们如何去使用他呢,先来听笔者啰嗦一段话吧!有个整体的概念。

共享内存,听这个名字就像已经知道他是什么东东了,既然我们现在学习的的Linux进程之间的通讯,所以这个共享内存肯定也离不开通讯的功能,是的,他是IPC中的重要一员,成为高手,也是必须要掌握的。

对于共享内存,Linux中共享内存的两种主要实现方式:System V和POSIX。没错又是两套API,关于这两套API,笔者就教大家如何使用System V吧,因为POSIX感觉并不常用,读者朋友们有兴趣可以自己学一学。

那么进入正题。

什么是共享内存

他总体的作用就是,在Linux当中开辟一段内存空间,使得两个进程可以同时访问,是的就是这么简单

具体操作可以具象为操作一个文件(毕竟Linux中一切皆是文件呢)

open一个文件(没有就创建他)
我可以使用read读取他,也可以使用write去修改他。
当然这个文件,也可以让所有进程看到,并操作。
这样说,我们理所当然的就学会了共享内存,我们对于一个文件的操作,其实就是对共享内存进行操作!

那么他有什么API呢,总不能和文件的open等等的API冲突吧,肯定也有自己的优势,方便之处吧,来看一下吧。

特性共享内存文件操作
速度直接在内存中操作,速度快涉及磁盘 I/O,速度较慢
内存共享多个进程可以直接共享数据每个进程通常创建自己的文件副本
资源利用内存使用更加高效,避免冗余每个进程可能会重复打开和关闭文件
数据一致性直接访问最新数据,避免不一致性可能需要额外同步机制保证一致性
适用场景高频率、大量数据交换持久化存储、日志记录等
复杂性需要管理访问权限和同步机制操作相对简单,易于理解
系统调用数量包含 shmget, shmat, shmdt, shmctl包含 open, read, write, close
  • 共享内存 更适合需要快速、高效的数据交换的场景,尤其是涉及到大量数据的实时处理。
  • 文件操作 更适合需要持久化存储和简单文件操作的场景。

查看和删除共享内存(拓展)
你可以使用 ipcs -m 查看共享内存段,并通过 ipcrm 删除它

System V 共享内存 API 引入

总之就是下面这一坨了

int shmget(key_t key, size_t size, int shmflg);  // 创建/获取共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg); // 附加到进程空间
int shmdt(const void *shmaddr);  // 分离共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf); // 控制操作

我们依次介绍他。大致看看即可,通过实例学习,不了解可以回来继续复习。🎯


1. shmget

功能:创建一个新的共享内存段或者获取一个已经存在的共享内存段的标识符。

原型

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

参数

  • key:用于标识共享内存段的键。可以通过 ftok 函数生成一个唯一的键。
  • size:共享内存段的大小(以字节为单位)。如果要创建新的共享内存段,此值必须大于 0。
  • shmflg:控制标志,可以包括以下选项:
    • IPC_CREAT:如果指定的共享内存段不存在,则创建它。
    • IPC_EXCL:与 IPC_CREAT 一起使用,如果共享内存段已经存在,则调用失败。
    • 权限标志(如 0666)指定谁可以读/写共享内存段。

返回值:成功时返回共享内存段的标识符(非负整数),失败时返回 -1,并设置 errno

示例

int shm_id = shmget(IPC_PRIVATE, 1024, IPC_CREAT | 0666);

2. shmat

功能:将共享内存段附加到调用进程的地址空间。

原型

void* shmat(int shm_id, const void* shmaddr, int shmflg);

参数

  • shm_id:通过 shmget 返回的共享内存段标识符。
  • shmaddr:希望共享内存段附加到的地址。通常可以设置为 NULL,由系统自动选择。
  • shmflg:控制标志,通常设置为 0。

返回值:成功时返回指向共享内存段的指针,失败时返回 (void*) -1,并设置 errno

示例

char* shm_ptr = (char*) shmat(shm_id, NULL, 0);

3. shmdt

功能:将共享内存段从调用进程的地址空间分离。

原型

int shmdt(const void* shmaddr);

参数

  • shmaddr:指向之前通过 shmat 返回的共享内存指针。

返回值:成功时返回 0,失败时返回 -1,并设置 errno

示例

if (shmdt(shm_ptr) == -1) {perror("shmdt failed");
}

4. shmctl

功能:控制共享内存段的操作,包括查询、修改和删除。

原型

int shmctl(int shm_id, int cmd, struct shmid_ds* buf);

参数

  • shm_id:共享内存段的标识符。
  • cmd:控制命令,可以是以下之一:
    • IPC_STAT:填充 shmid_ds 结构体(用于获取共享内存信息)。
    • IPC_RMID:标记共享内存段为待删除。
    • IPC_SET:修改共享内存段的权限和其他信息(需要提供相应的 shmid_ds 结构体)。
    • IPC_INFO:获取系统共享内存的信息(通常是系统级的)。
  • buf:指向 shmid_ds 结构体的指针,用于输入/输出的控制信息。

返回值:成功时返回 0,失败时返回 -1,并设置 errno

示例(删除共享内存段):

if (shmctl(shm_id, IPC_RMID, NULL) == -1) {perror("shmctl IPC_RMID failed");
}

5. 结构体 shmid_ds

用于描述共享内存段的状态,包括以下字段:

struct shmid_ds {struct ipc_perm shm_perm; // 共享内存的权限size_t shm_segsz;         // 共享内存段的大小time_t shm_atime;         // 最后附加时间time_t shm_dtime;         // 最后分离时间time_t shm_ctime;         // 最后控制时间unsigned short shm_cpid;  // 创建该共享内存段的进程 IDunsigned short shm_lpid;  // 最后操作该共享内存段的进程 IDshort shm_nattch;         // 当前附加到该共享内存段的进程数
};

开始实操

通过上述 API,可以有效地创建和管理共享内存段,从而实现进程间的高效通信。在使用共享内存时,务必注意同步问题,以避免数据竞争和不一致性。对于更复杂的应用,可能需要结合其他 IPC 机制(如信号量)来实现更可靠的进程间通信。

我们先简单的利用API来实现两个程序,一个写入,一个读取。

写入进程:

#include <sys/ipc.h>
#include <sys/shm.h>#define SHM_SIZE 1024int main() {key_t key = ftok("shmfile", 65);int shmid = shmget(key, SHM_SIZE, 0666|IPC_CREAT);char *str = (char*) shmat(shmid, NULL, 0);sprintf(str, "Hello from PID %d", getpid());shmdt(str);return 0;
}

读取进程:

// ...(头文件同上)
int main() {key_t key = ftok("shmfile", 65);int shmid = shmget(key, SHM_SIZE, 0666);char *str = (char*) shmat(shmid, NULL, 0);printf("Received: %s\n", str);shmdt(str);shmctl(shmid, IPC_RMID, NULL); // 删除共享段return 0;
}

这里仅仅做了这样一个小实验,随着日后,技术的提升,不断迭代,希望读者可以灵活应用,这里没有加入其它IPC同步机制,实际使用,对于共享内存的访问是要做保护机制的!!!仅仅让读者快速掌握他如何使用。

监控与调试技巧 使用ipcs -m查看System V共享段

通过lsof /dev/shm检查POSIX对象

分析/proc/sysvipc/shm获取详细信息

使用strace跟踪shm相关系统调用

注意

同步机制(必须实现以下之一):

使用共享内存必须必须使用同步机制,避免同时访问或者操作,造成数据错乱或者死机

  • 信号量(semaphore)

  • 互斥锁(pthread_mutex,需配置进程共享属性)

  • 文件锁(fcntl)

生命周期管理:

  • System V:需主动调用shmctl(IPC_RMID)

  • POSIX:引用计数归零后自动删除

安全配置:

  • 严格设置权限位(如0600)

  • 避免使用可预测的IPC键值

  • 及时清理未使用的共享段

性能调优:

  • 使用大页内存(Hugepages)

  • 对齐内存访问边界

  • 避免频繁attach/detach操作

结束

浅浅的总结一下吧,这节我们学到了System V共享内存,以及他的一些核心API的使用,知道了他是什么东西。虽然操作文件的大致流程上没有俩样。但是使用上还是更具实际情况选择哦,并且给了两段小程序来帮助理解,再次提醒,实际情况,要做同步机制保护。
好了,本文就到这里了,让我们每天进步一小步吧!

相关文章:

《Linux系统编程篇》共享内存(Linux 进程间通信(IPC))——基础篇

文章目录 引言什么是共享内存System V 共享内存 API 引入1. shmget2. shmat3. shmdt4. shmctl5. 结构体 shmid_ds 开始实操注意 结束 今天的你有没有前进一小步呢 ——家驹(StrangeHead) 引言 那么共享内存&#xff0c;我们如何去使用他呢&#xff0c;先来听笔者啰嗦一段话吧…...

【EB-03】 AUTOSAR builder与EB RTE集成

AUTOSAR builder与EB RTE集成 1. Import Arxml files to Tresos2. Run MultiTask Script3. Add Components3.1 Run EcuExtractCreator Script4. Mapping Component to Partitions5. Event Mapping/Runnables Mapping to Tasks6. Port Connect7. Run SvcAs_Trigger Script8. Ver…...

HTML——前端基础1

目录 前端概述 前端能做的事情​编辑 两步完成一个网页程序 前端工具的选择与安装 HTML HTML5介绍 HTML5的DOCTYPE声明 HTML基本骨架 文字标签 标题之标签 标签之段落、换行、水平线 标签之图片 标签之超文本链接 标签之文本 列表标签之有序列表 列表标签之无序…...

AI回答:Linux C/C++编程学习路线

Linux C/C编程学习路线需要结合Linux系统特性和C/C语言的特点&#xff0c;以下是一个系统化的学习路径&#xff0c;适合从初学者到进阶者&#xff1a; 第一阶段&#xff1a;Linux基础 Linux操作系统基础 学习Linux基本命令&#xff1a;ls、cd、mkdir、rm、grep、find等。 理解…...

螺旋数字矩阵

螺旋数字矩阵 真题目录: 点击去查看 E 卷 100分题型 题目描述 疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法: 给出数字个数n和行数m(0 < n ≤ 999,0 < m ≤ 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3…n,最终形成一…...

Jupyter Notebook切换虚拟环境(Kernel管理)

我们在使用Jupyter Notebook的时候&#xff0c;打开文件发现只有一个Python3(ipykernel)&#xff0c;我们自己在conda中创建的虚拟环境为什么没有显示出来&#xff0c;今天我就来和大家一起讨论一下&#xff01; 在 Jupyter Notebook 中&#xff0c;kernel 是执行代码的核心。管…...

linux下软件安装、查找、卸载

目录 常见安装方式有三种&#xff1a; 1.源码安装。 2.rpm安装方式。 3.yum/apt工具级别安装。 对于前两种安装方式&#xff0c;因为软件可能有依赖关系&#xff08;安装的软件依赖于某些库&#xff0c;而这些库又依赖于某些库&#xff0c;这些都需要手动安装&#xff09;…...

vuetify项目添加代理跨域请求

vuetify项目添加代理转发后端接口实现跨域请求 配置一&#xff08;推荐&#xff09;配置二 在项目根目录下找到vite.config.mts文件并在里面的server下配置代理&#xff0c; 具体实现代码如下&#xff1a; 配置一&#xff08;推荐&#xff09; server: {port: 3000,// 配置代理…...

H5 火柴人科目三和GitHub获取仓库点星星的用户列表发生了艺术的碰撞

先看效果&#xff0c;代码写的比较乱&#xff0c;有待优化 效果 https://linyisonger.github.io/H5.Examples/?name./089.%E7%9C%8B%E6%98%9F%E6%98%9F%E7%9A%84%E8%88%9E%E8%80%85.html 思路 看起来很简单&#xff0c;实则也不是很难&#xff0c;就是需要思路要打开。 一…...

【Azure 架构师学习笔记】- Azure Databricks (12) -- Medallion Architecture简介

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (11) – UC搭建 前言 使用ADB 或者数据湖&#xff0c;基本上绕不开一个架构“Medallion”&#xff0c; 它使得数据管理更为简单有效。ADB 通过…...

基础知识|原型在什么时候用和类的区别

在 JavaScript 中&#xff0c;原型和类是两个密切相关但有所不同的概念。理解这两者之间的差异有助于更好地掌握面向对象编程&#xff08;OOP&#xff09;在 JavaScript 中的实现。 1. 原型&#xff08;Prototype&#xff09; 原型是 JavaScript 中实现继承和共享行为的核心机…...

【FFmpeg】拉流

概述 项目实践中涉及到使用ffmpeg进行推流和拉流操作&#xff0c;本文主要对一些基本操作做一个学习总结&#xff0c;后续再学习其源码架构&#xff1b;总结方法遵循实现功能配合函数具体实现 基本使用 拉流 avformat_network_init();//日志输出等级set_ffmpeg_log_level();…...

LangChain构建行业知识库实践:从架构设计到生产部署全指南

文章目录 引言:行业知识库的进化挑战一、系统架构设计1.1 核心组件拓扑1.2 模块化设计原则二、关键技术实现2.1 文档预处理流水线2.2 混合检索增强三、领域适配优化3.1 医学知识图谱融合3.2 检索结果重排序算法四、生产环境部署4.1 性能优化方案4.2 安全防护体系五、评估与调优…...

解决jupyter notebook不是内部或外部命令问题

我们打开cmd有的时候&#xff0c;输入jupyter notebook&#xff0c;发现会提示jupyter 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。遇到这个问题我们应该怎么解决呢? 没错就是添加环境变量&#xff01; Step01&#xff1a;在电脑中找到jupyter notebook的…...

MySQL----case的用法

在 MySQL 中&#xff0c;CASE 表达式是一个用于条件判断的功能&#xff0c;可以根据不同的条件返回不同的结果。CASE 表达式通常用于 SELECT 查询语句中&#xff0c;可以在 SQL 中灵活地进行条件判断和数据转换。CASE 有两种基本的语法形式&#xff1a; 简单 CASE 表达式&…...

Unity XR-XR Interaction Toolkit开发使用方法(十)组件介绍(XR Interaction Group)

目录 一、插件介绍 二、主要组件 XR Interaction Manager XR Controller XR Interactor XR Direct Interactor XR Ray Interactor XR Socket Interactor XR Gaze Interactor 三、XR Interaction Group 1、组件介绍 2、核心功能与特点 优先级与冲突管理 动态交互切…...

深入理解 并查集LRUCaChe

并查集&LRUCaChe 个人主页&#xff1a;顾漂亮 文章专栏&#xff1a;Java数据结构 1.并查集的原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后根据一定规律将归于同一组元素的…...

详解 c++ 中的 namespage

C 中的命名空间很特别&#xff0c;其他编程语言基本都没有。命名空间介于函数与类之间&#xff0c;兼顾了二者的一些优点。这篇博客根据 chatgpt 的回答整理。 文章目录 **1. 什么是 namespace&#xff08;命名空间&#xff09;&#xff1f;****2. 语法****3. 使用 namespace 访…...

50周学习go语言:第五周 复合类型与词频统计

以下是第五周复合类型&#xff08;数组、切片与映射&#xff09;的详细学习内容&#xff0c;按照第四周的深度要求设计&#xff1a; 第五周&#xff1a;复合类型与词频统计 一、复合类型详解 1. 数组&#xff08;Array&#xff09; // 声明与初始化 var arr1 [3]int …...

HTTP非流式请求 vs HTTP流式请求

文章目录 HTTP 非流式请求 vs 流式请求一、核心区别 服务端代码示例&#xff08;Node.js/Express&#xff09;非流式请求处理流式请求处理 客户端请求示例非流式请求&#xff08;浏览器fetch&#xff09;流式请求处理&#xff08;浏览器fetch&#xff09; Python客户端示例&…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...