仓库地址https://gitee.com/tgwTTT/linux-learning-dai/tree/master/Shm
一、共享内存的原理与OS管理
共享内存是操作系统提供的一种高效进程间通信(IPC)机制。所有的底层管理工作都由操作系统自动完成,包括内存分配、映射、权限控制和资源回收。我们只需要通过系统调用完成创建、连接、读写和删除等操作。
取消关联关系后,OS会自动释放进程的虚拟地址映射,但共享内存本身的物理空间只有在明确删除后才会被释放。
一个共享内存段可以被多个进程同时映射和访问,实现数据共享。
二、系统调用与参数说明
1. 常用系统调用
shmget(key, size, shmflg):创建或获取共享内存段。

shmat(shmid, addr, flag):将共享内存映射到进程虚拟地址空间。

shmdt(addr):解除映射关系(detach)。

shmctl(shmid, IPC_RMID, 0):删除共享内存段。

2. 命令行工具
ipcs -m:查看当前系统所有共享内存段。

ipcrm -m:删除指定的共享内存段。
注意:
即使进程退出,只要没有删除共享内存段,资源会一直存在,生命周期随内核。
三、代码举例
用了共享内存作为数据交换区,server 进程负责创建共享内存并读取数据,client 进程负责连接共享内存并写入数据。
为保证同步,配合 FIFO 管道实现唤醒通知
- 共享内存管理(Shm.hpp)
Shm 类封装了共享内存的创建、连接、映射和销毁。
server 用 CREATER 模式创建,client 用 USER 模式连接。
部分代码举例:
void Attach()
{
_start_mem = shmat(_shmid, nullptr, 0);
if ((long long)_start_mem < 0)
{
ERR_EXIT("shmat");
}
printf("attach success\n");
}
void Detach()
{
int n = shmdt(_start_mem);
if (n == 0)
{
printf("detach success\n");
}
}
void CreateHelper(int flg)
{
printf("key: 0x%x\n", _key);
// 共享内存的生命周期,随内核
_shmid = shmget(_key, _size, flg);
if (_shmid < 0)
{
ERR_EXIT("shmget");
}
printf("shmid: %d\n", _shmid);
}
Shm(const std::string &pathname, int projid, const std::string &usertype)
: _shmid(gdefaultid),
_size(gsize),
_start_mem(nullptr),
_usertype(usertype)
{
_key = ftok(pathname.c_str(), projid);
if (_key < 0)
{
ERR_EXIT("ftok");
}
if (_usertype == CREATER)
Create();
else if (_usertype == USER)
Get();
else
{
}
Attach();
}
void *VirtualAddr()
{
printf("VirtualAddr: %p\n", _start_mem);
return _start_mem;
}
int Size()
{
return _size;
}
void Attr()
{
struct shmid_ds ds;
int n = shmctl(_shmid, IPC_STAT, &ds); // ds:输出型参数
printf("shm_segsz: %ld\n", ds.shm_segsz);
printf("key: 0x%x\n", ds.shm_perm.__key);
}
今天的更新就到这里,如有错误欢饮指出!!
评论
读起来像小说。感谢 心情。
我很少遇到, 这么鲜明的文字。点赞。 德涅斯特峡谷 我尊重这样的项目, 这里有真诚的评论。你的博客 就是 属于这里的。很出色。