除了System V风格的进程间通讯外,还有一套POSIX的接口和实现。
先查一下文档:
shm_open(3) - Linux man page
Name
shm_open, shm_unlink - create/open or unlink POSIX shared memory objects
Synopsis
#include <sys/mman.h>
#include <sys/stat.h> /* For mode constants */
#include <fcntl.h> /* For O_* constants */
int shm_open(const char *name, int oflag, mode_t mode);
int shm_unlink(const char *name);
Link with -lrt.
背后的实现机制,文档里也说了:
The POSIX shared memory object implementation on
Linux 2.4 makes use of a dedicated file system,
which is normally mounted under /dev/shm.
这套API的操作实际上就是在/dev/shm下帮你新建了一个文件,然后可能帮你检查了一些环境要求。
鉴于/tmp和/dev/shm一样,都是系统自动挂载的tmpfs。
那我悟到了,以后要共享数据的时候,直接往/tmp里扔就行了。
/tmp和/dev/shm的默认大小都是最大内存的一半,这个有接口可以改。超出之后会触发swap之类的机制,可能因人而异。
在实践中,使用POSIX 的接口新建共享内存之后往里面写字符串,然后直接去cat /dev/shm下的文件都可以完整读取到,可见如果我自己不加机制来保护,那这个数据完全就是全局可见。
最后,喷一下 C 语言里的文件读写真的是难用。最后还是靠mmap这一套来实现了。不过损失了文件大小可伸缩的灵活特性。。
下面放上宋宝华老师的示例代码。他没unlink,不过毕竟tmpfs,无伤大雅。
写端:
读端:
使用mmap的好处就是,进行内存映射之后,在代码里就是无感使用了,用起来和local的数据结构一样。注意要(char *)mmap这样显示类型转化,不然在C++ 下可能会编译器报错或warn。