部分概念摘录自《UNIX环境高级编程》
多个进程共享同一块存储区域。
本机制本身不提供读写保护等同步异步机制。需要搭配信号量、锁等其他机制使用。
那如果我写个父子进程、代码执行本身是有先后顺序的,那是不是本身就线程安全了,不需要加同步机制了?
实现的原理是,将同一个文件映射到多个进程的地址空间。
调用的第一个函数通常是shmget,它获得一个共享存储标识符。
#include <sys/shm.h>
int shmget(key_t key, size_t size, int flag);
返回值:若成功,返回共享存储ID;若出错,返回−1
对于key 和 flag。
有3种称作XSI IPC的IPC:消息队列、信号量以及共享存储器。
他们都是发源于System V.
每个内核中的IPC结构(消息队列、信号量或共享存储段)都用一个非负整数的标识符(identifier)加以引用。
当一个IPC结构被创建,然后又被删除时,与这种结构相关的标识符连续加1,直至达到一个整型数的最大正值,然后又回转到0。(我觉得 一般也不会回转到0)
标识符在IPC对象内部使用。在外部,通过键(Key)识别。
创建IPC结构时(通过调用msgget、semget或shmget创建),需要指定Key.类型为key_t,定义在<sys/type.h>中。内核实现key到标识符的内外转换。
可用方法:
约定一个路径名和项目ID(0~255),使用ftok生成Key.
#include <sys/ipc.h>
key_t ftok(const char *path, int id);
返回值:若成功,返回键;若出错,返回(key_t)−1
path参数必须引用一个现有的文件。当产生键时,只使用id参数的低8位。
对于不同文件的两个路径名,如果使用同一项目ID,那么可能产生相同的键,因为在引用路径数据结构中的信息的时候可能会产生数据截断丢失精度。
key 和 flag的使用:
创建新的IPC:key是IPC_PRIVATE或别的,flag指明IPC_CREAT.
使用IPC_PRIVATE创建的IPC需要通过标识符调用,而可用避免反复使用get函数。
使用已有IPC:Key用创建时的key,不设IPC_CREAT。
对于这种方法,宋宝华老师评价为:
历史悠久、年代久远、API怪异,对应内核代码linux/ipc/shm.c,当你编译内核的时候不选择CONFIG_SYSVIPC,则不再具备此能力。
你在Linux敲ipcs命令看到的share memory就是这种共享内存。
参考代码:

