在 C++ 中跨程序共享指针

Sharing pointer across programs in C++

这与之前的post相关:

我想要一个生成巨大矩阵 M 的单个 C++ 服务器 运行ning。然后,在同一台机器上,我想 运行 可以联系该服务器的其他程序,并获取 M 的内存地址。 M只读,服务器创建一次。我应该能够生成一个客户端 ./test,并且该程序应该能够对 M 进行只读访问。服务器应始终 运行ning,但我可以随时 运行 其他程序,例如 ./test

我不太了解 C++ 或 OS,最好的方法是什么?我应该使用 POSIX 线程吗?矩阵是原始类型(doublefloat 等),所有程序都知道它的维度。客户端程序需要整个矩阵,所以我不希望从服务器到客户端的内存复制有延迟,我只想直接共享该指针。我最好的选择是什么?

当然其他程序不能访问矩阵,只要它在"normal"进程内存中。

毫无疑问的设计方法:是的,你必须使用共享内存。查找函数,如 shmget()、shmat() 等。然后您不需要将指针传递给另一个程序(实际上这不会起作用),您只需在 ftok() 中到处使用相同的文件即可访问共享内存。

您绝对可以用来共享对矩阵 M 的直接访问的一种进程间通信机制是 共享内存。这意味着 OS 允许多个进程访问内存中的共享段,就好像它在它们的地址 space 中一样,方法是为每个请求映射它。 boost::interprocess 可以满足您的所有要求并且是跨平台的解决方案。它是一个薄的可移植层,包装了所有必要的 OS 调用。请参阅右侧的工作示例 here in the docs

基本上,您的服务器进程只需要创建一个 boost::interprocess::shared_memory_object 类型的对象,为构造函数提供共享段的 名称 。当调用其 truncate() 方法时,OS 将在此服务器进程的地址 space 中寻找足够大的段。从这一刻起,任何其他进程都可以创建相同类型的对象并提供相同的名称。现在它也可以访问完全相同的内存。不涉及副本。

如果由于某种原因您无法使用可移植的 Boost 库,或者由于其他原因想要将支持的平台限制为 Linux,请使用 POSIXAPI周围mmap() function. Here's the Linux man page. Usage is basically not far from the Boost pipeline described above. you create the named segment with shm_open() and truncate with ftruncate(). From there onwards you receive the mapped pointer to this allocated space by calling mmap(). In simpler cases where you'll only be sharing between parent and child processes, you can use this code example from this very website.

当然,无论您采用何种方法,在使用共享资源时,请确保正确同步 read/writes 以避免任何竞争条件——就像您在多线程场景中所做的那样相同的过程。