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

Linux IPC:System V共享内存汇总整理

System V 共享内存是 Unix 和类 Unix 操作系统中的一种进程间通信(IPC)机制,它允许进程之间共享同一块内存区域。System V 共享内存是 System V IPC 标准的一部分,该标准还包括信号量和消息队列等其他 IPC 机制。

概述

System V 共享内存允许进程通过映射同一块内存区域来共享数据。与其他 IPC 机制相比,共享内存提供了更高的效率,因为它不需要复制数据就可以在进程之间传递信息。

特点

  • 持久性:共享内存段可以持久存储在内核中,即使创建它的进程终止后仍然存在。
  • 跨进程:共享内存可以在没有亲缘关系的进程之间进行通信。
  • 属性配置:可以配置共享内存段的属性,如最大大小等。

API

System V 共享内存主要由以下几个函数组成:

创建共享内存段

  • shmget():
    • int shmget(key_t key, size_t size, int shmflg): 创建或打开共享内存段。
    • 参数key是标识共享内存段的键值,size指定共享内存段的大小,shmflg指定标志位,可以包含IPC_CREAT来创建新的共享内存段,也可以包含IPC_EXCL来防止创建已存在的共享内存段。

映射共享内存

  • shmat():
    • void *shmat(int shmid, const void *shmaddr, int shmflg): 将共享内存段映射到进程地址空间。
    • 参数shmid是共享内存段标识符,shmaddr指定映射的起始地址,如果为NULL则由系统选择,shmflg指定标志位。

取消映射共享内存

  • shmdt():
    • int shmdt(const void *shmaddr): 取消映射共享内存段。
    • 参数shmaddr是映射的起始地址。

删除共享内存段

  • shmctl():
    • int shmctl(int shmid, int cmd, ... /* union shmid_ds *buf */): 控制共享内存段。
    • 参数shmid是共享内存段标识符,cmd指定命令,如IPC_RMID用于删除共享内存段,后面的参数根据命令的不同而变化。

示例代码

下面是一个简单的示例,展示了如何使用 System V 共享内存来在两个进程之间共享数据:

进程 A (processA.c)

1#include <sys/types.h>
2#include <sys/ipc.h>
3#include <sys/shm.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8#define SHM_KEY 12345
9#define SHM_SIZE 1024
10
11int main() {
12    int shmid;
13    char *shm_ptr;
14
15    // 创建共享内存段
16    shmid = shmget(SHM_KEY, SHM_SIZE, 0666 | IPC_CREAT);
17    if (shmid == -1) {
18        perror("shmget");
19        exit(EXIT_FAILURE);
20    }
21
22    // 映射共享内存段到进程地址空间
23    shm_ptr = shmat(shmid, NULL, 0);
24    if (shm_ptr == (void *)-1) {
25        perror("shmat");
26        exit(EXIT_FAILURE);
27    }
28
29    // 写入数据
30    strncpy(shm_ptr, "Hello, World!", SHM_SIZE);
31
32    // 取消映射
33    if (shmdt(shm_ptr) == -1) {
34        perror("shmdt");
35        exit(EXIT_FAILURE);
36    }
37
38    return 0;
39}

进程 B (processB.c)

1#include <sys/types.h>
2#include <sys/ipc.h>
3#include <sys/shm.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8#define SHM_KEY 12345
9#define SHM_SIZE 1024
10
11int main() {
12    int shmid;
13    char *shm_ptr;
14
15    // 打开共享内存段
16    shmid = shmget(SHM_KEY, SHM_SIZE, 0666);
17    if (shmid == -1) {
18        perror("shmget");
19        exit(EXIT_FAILURE);
20    }
21
22    // 映射共享内存段到进程地址空间
23    shm_ptr = shmat(shmid, NULL, 0);
24    if (shm_ptr == (void *)-1) {
25        perror("shmat");
26        exit(EXIT_FAILURE);
27    }
28
29    // 读取数据
30    printf("Data in shared memory: %s\n", shm_ptr);
31
32    // 取消映射
33    if (shmdt(shm_ptr) == -1) {
34        perror("shmdt");
35        exit(EXIT_FAILURE);
36    }
37
38    // 删除共享内存段
39    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
40        perror("shmctl");
41        exit(EXIT_FAILURE);
42    }
43
44    return 0;
45}

编译和运行

为了编译上述代码,你可以使用以下命令:

1gcc -o processA processA.c
2gcc -o processB processB.c

然后运行这两个进程:

1./processA &
2./processB

注意事项

  • 在使用 System V 共享内存之前,确保检查所有 API 调用的返回值,以确保操作成功。
  • 当使用完共享内存后,记得取消映射并删除共享内存段以释放资源。
  • 如果共享内存段不再需要,应使用 shmctl() 的 IPC_RMID 命令删除它,以避免占用不必要的系统资源。
  • 在实际应用中,可能需要处理更复杂的错误情况,比如处理映射失败的情况。

System V 共享内存提供了一种简单而强大的机制来进行进程间的共享数据,非常适合那些需要快速访问共享数据的应用场景。理解和熟练掌握这些 API 对于开发可靠的多进程应用程序非常重要。

 


http://www.kler.cn/a/581855.html

相关文章:

  • 理解 XSS 和 CSP:保护你的 Web 应用免受恶意脚本攻击
  • 多光谱相机数据采集过程中常见仪器
  • <rust><tauri><GUI>基于tauri,打开任意windows电脑应用程序
  • 如何手动下载spring jar包
  • Vue.js 全面解析:构建现代前端应用的渐进式框架
  • SPA应用优化首屏加载速度
  • C++20 新特性总结
  • AWS原生架构下的服务器性能与成本平衡之道——海外业务云端实践
  • 用Python实现链上数据爬取与分析
  • RISC-V特权模式与寄存器
  • MATLAB 控制系统设计与仿真 - 22
  • 从零开始用AI开发游戏(一)
  • 关于在electron(Nodejs)中使用 Napi 的简单记录
  • 【GPT入门】第6课 openai接口介绍与参数说明
  • 远程手机遥控开关原理及应用
  • git commit messege 模板设置 (规范化管理git)
  • 机器学习基础(4)
  • 清华同方国产电脑能改windows吗_清华同方国产系统改win7教程
  • 《PaddleOCR》—— OCR
  • Agentic RAG 详解 - 从头开始​​构建你自己的智能体系统