【问题标题】:Sharing pointer across programs in C++在 C++ 中跨程序共享指针
【发布时间】:2018-08-29 05:16:34
【问题描述】:

这与之前的帖子有关:

Allocating a large memory block in C++

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

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

【问题讨论】:

标签: c++ shared-memory


【解决方案1】:

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

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

如果由于某种原因您无法使用可移植的 Boost 库,或者出于其他原因想要将支持的平台限制为 Linux,请使用 mmap() function 周围的 POSIX API。这是Linux man page。用法基本上离上面介绍的Boost管道不远了。您使用shm_open() 创建命名段并使用ftruncate() 创建截断。从那里开始,您通过调用mmap() 接收指向该分配空间的映射指针。在您只在父进程和子进程之间共享的更简单的情况下,您可以使用this code example from this very website

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

【讨论】:

  • 矩阵是只读的,所以我认为我不需要担心锁或同步。如果我假设一个 Linux 环境,并且不想使用Boost,那么最好的选择是什么?
  • @SpentDeath 已编辑以适应您所说的假设 Linux 的场景:)
【解决方案2】:

当然,只要它在“正常”进程内存中,其他程序就无法访问矩阵。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 2012-03-28
    相关资源
    最近更新 更多