菜鸟笔记
提升您的技术认知

操作系统笔记

进程,线程,协程与并行,并发进程线程协程的区别死锁进程,线程,多线程i++的线程安全性同步和异步孤儿进程和僵尸进程/proc进程信息linux中的分段和分页互斥量 mutex线程进程间通信进程创建进程优先级进程的基础知识进程与线程的区别(面试题)线程的控制(创建,终止,等待,分离)可重入 VS 线程安全死锁的概念一级缓存和二级缓存的理解一句话解说内存屏障 Memory barrierbrk(), sbrk() 用法详解malloc/free函数的简单实现一文讲透 “进程、线程、协程”Linux进程状态线程池的陷阱linux内核学习之进程和线程进程与线程的区别和联系内存寻址linux IO子系统和文件系统读写流程Page cache和buffer cache的区别与联系漫谈linux文件IO多线程和多进程的区别内存泄漏字节、字、位、比特的概念和关系如何避免死锁ANSI是什么编码?CPU寻址范围(寻址空间)CPU 使用率低高负载的原因创建多少个线程合适操作系统下spinlock锁解析、模拟及损耗分析线程堆栈堆和栈的内存分配堆和栈的概念和区别堆和栈的区别,申请方式,程序的内存分配什么是 POD 数据类型Linux内存分配小结--malloc、brk、mmap系统调用与内存管理(sbrk、brk、mmap、munmap)进程描述和控制CPU执行程序的原理编译的基本概念Linux虚拟地址空间布局一个程序从源代码到可执行程序的过程程序的运行机制——CPU、内存、指令的那些事分页内存管理——虚拟地址到物理地址的转换深刻理解Linux进程间通信fork之后父子进程的内存关系fork之后,子进程继承了父进程哪些内容关于协程及其锁的一些认识对协程的一点理解std::thread join和detach区别CAS和ABA问题CAS算法锁和无锁无锁队列的实现Lock-Free 编程锁开销优化以及CAS进程、线程和协程之间的区别和联系多线程的同步与互斥(互斥锁、条件变量、读写锁、自旋锁、信号量)Linux 原来是这么管理内存的线程上下文切换怎么玩儿进程和线程通信原理CPU密集型 和 IO密集型cas原理以及Atomic原子类分析改变线程状态的八个方法六种进程间通信方式进程和线程的区别系统调用进程的概念linux共享内存进程间通讯方式进程的调度线程同步的方式mmap和shm 区别

linux共享内存

阅读 : 116

Linux 共享内存(Shared Memory)

概述

共享内存是 Linux 中进程间通信(IPC)的一种高效机制。它允许多个进程直接访问同一块物理内存区域,避免了数据拷贝的开销,是速度最快的 IPC 方式。


核心特点

  • 高效性:进程直接读写内存,无需系统调用或数据复制。
  • 无结构化:共享内存本身不提供同步机制,需结合其他方式(如信号量)保证数据一致性。
  • 内核持久性:共享内存区域在内核中维护,直到显式删除或系统重启。

实现方式

Linux 支持两种共享内存实现:

类型 特点
System V 传统实现方式,通过 shmget/shmat 等函数操作。
POSIX 现代实现方式,基于内存映射文件(mmap),更符合 POSIX 标准。

System V 共享内存操作步骤

1. 创建/获取共享内存

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);
  • 参数:
    • key:唯一标识符(通常用 ftok() 生成)

    • size:共享内存大小(字节)

    • shmflg:权限标志(如 IPC_CREAT | 0666)

  • 返回值:共享内存标识符(shmid)

  1. 附加到进程地址空间
void *shmat(int shmid, const void *shmaddr, int shmflg);
  • 参数:

    • shmid:共享内存标识符

    • shmaddr:指定附加地址(通常设为 NULL,由系统选择)

    • shmflg:附加标志(如 SHM_RDONLY 只读访问)

  • 返回值:指向共享内存的指针

  1. 使用共享内存
// 写入数据
sprintf((char*)shared_memory, "Hello from PID %d", getpid());
// 读取数据
printf("Received: %s\n", (char*)shared_memory);
  1. 分离共享内存
int shmdt(const void *shmaddr);
  • 参数:shmaddr 为 shmat() 返回的指针
  1. 删除共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
  • 用法:设置 cmd 为 IPC_RMID
shmctl(shmid, IPC_RMID, NULL);

POSIX 共享内存示例

#include <sys/mman.h>
#include <fcntl.h>

// 创建共享内存对象
int fd = shm_open("/my_shm", O_CREAT | O_RDWR, 0666);
ftruncate(fd, SIZE);

// 映射到进程地址空间
void *ptr = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

// 使用后清理
munmap(ptr, SIZE);
shm_unlink("/my_shm");

常用命令

# 查看所有共享内存段
ipcs -m

# 删除共享内存段(System V)
ipcrm -m <shmid>

# 查看 POSIX 共享内存对象
ls /dev/shm