0%

C++-共享内存初探

共享内存基础

维基百科对共享内存定义如下:

In computer science, shared memory is memory that may be simultaneously accessed by multiple programs with an intent to provide communication among them or avoid redundant copies. Shared memory is an efficient means of passing data between programs. Depending on context, programs may run on a single processor or on multiple separate processors.

从定义中可以看到相关关键技术:多进程(线程),并发,沟通。因此脑海有一个大概的概念,多个进程,共享同一片内存空间,高效地进行数据交换,并通过一些例如信号量的方式来避免冲突产生。

共享内存的生命周期

首先说结论,共享内存的生命周期是独立于所有与其相关的进程。换句话说,在进程内如果不主动回收这块内存空间,及时进程退出后,这块空间仍然的独立存在的。这种特性与常见的栈内存、堆内存不同。正因为这个特性使得很多本地缓存都选择放在共享内存中,当进程因为各种原因(coredump,热更新。。。)重启后,仍然能通过某种方式读取到原有数据,从而达到不影响用户(上游)使用(调用)的目的,保障服务质量。

创建共享内存

主流的共享内存创建方法有两种System VPOSIX

System V

System V在1983年有AT&T提出的商业化Unix版本,其定义了若干共享内存的创建、绑定和销毁接口

1
2
3
4
5
6
7
8
9
10
// 创建key
key_t ftok(const char *_pathname_, int _proj_id_);
// 分配共享内存
int shmget(key_t _key_, size_t _size_, int _shmflg_);
// 将分配的物理内存ID绑定到调用进程的地址空间上
void *shmat(int _shmid_, const void *_Nullable _shmaddr_, int** _shmflg_);
// 解绑
int shmdt(const void *_shmaddr_);
// 控制函数,可以用IPC_RMID命令来标记共享内存处于回收状态(只有创建进程或者拥有进程可以标记)
int shmctl(int _shmid_, int _cmd_, struct shmid_ds *_buf_);

POSIX

1
2
3
4
5
6
7
8
9
10
// 创建共享内存
int shm_open(const char *_name_, int _oflag_, mode_t _mode_);
// 给指定_fd__分配指定长度内存
int ftruncate(int _fd_, off_t _length_);
// 将_addr_地址开始的_length_长度的内存映射到调用进程的地址空间上
void *mmap(void _addr_[._length_], size_t _length_, int _prot_, int _flags_, int _fd_, off_t _offset);
// 解绑
nt munmap(void _addr_[._length_], size_t _length_);
// 回收共享内存
int shm_unlink(const char *_name_);