我有两个进程 P1 和 P2。
我有一个大型只读资源,称为“R”,我希望 P1 和 P2 都可以访问它。
R 不仅仅是一个“扁平”的字节组;它是一堆相互指向的 C++ 对象。
我希望 P1 和 P2 只共享 R 的一个副本 - 以某种方式让 P1 将 R 加载到内存中的一个区域(在 P1 和 P2 中映射到同一地址),然后 P1 和 P2 都可以访问 R 中的对象C++ 对象(没有竞争条件,因为都是只读的)。
任何熟悉如何做到这一点/陷阱的人?
实际上之前已经提出并解决了类似的问题:
最好的答案可能对你有用:使用boost interprocess library。虽然您仍然不能使用具有虚函数的对象(共享内存问题之外的讨厌的 vtable 指针),但它们确实有工具可以让您使用指向共享内存内其他对象的智能指针,以及在共享内存内分配用于创建的自定义分配器std::vector 和 std::map 对象。
R中的对象如何相互指向?如果它相对于当前对象的位置,您可以使用共享内存。无法保证此共享内存会在进程 P1 和 P2 的同一地址位置加载。这就是为什么相对只有效。既然你说,他们都不会尝试修改它并从中读取,我想你不需要使用信号量/互斥锁来保护它。
如果我理解手册页,那么如果您提供听起来有些吓人的 MAP_FIXED 选项, Linux mmap 功能似乎允许您将文件、共享内存或其他可映射的东西映射到特定虚拟地址的进程中。在手册页中搜索 MAP_FIXED,您会发现许多警告(可能不受支持,可能使 malloc 不再工作,等等)。但是如果你能让它工作,共享对象可以有彼此的指针。
就这么简单:
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
// ...
int fd = open("memfile.txt",O_RDWR);
struct stat info;
fstat(fd, &info);
void * page = mmap(0, info.st_size, PROT_READ , MAP_SHARED, fd, 0);
现在,您可以使用存储在 memfile.txt 中的任何内容作为结构,并将在进程之间共享。
注意正如其他人所说,您不能在这块内存中的对象之间使用指针。
这适用于我在 OS X 10.4 上,但应该适用于任何 BSD 兼容系统。