在 C++ 中跨程序共享指针
Sharing pointer across programs in C++
这与之前的post相关:
我想要一个生成巨大矩阵 M
的单个 C++ 服务器 运行ning。然后,在同一台机器上,我想 运行 可以联系该服务器的其他程序,并获取 M
的内存地址。 M
只读,服务器创建一次。我应该能够生成一个客户端 ./test
,并且该程序应该能够对 M
进行只读访问。服务器应始终 运行ning,但我可以随时 运行 其他程序,例如 ./test
。
我不太了解 C++ 或 OS,最好的方法是什么?我应该使用 POSIX 线程吗?矩阵是原始类型(double
、float
等),所有程序都知道它的维度。客户端程序需要整个矩阵,所以我不希望从服务器到客户端的内存复制有延迟,我只想直接共享该指针。我最好的选择是什么?
当然其他程序不能访问矩阵,只要它在"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 以避免任何竞争条件——就像您在多线程场景中所做的那样相同的过程。
这与之前的post相关:
我想要一个生成巨大矩阵 M
的单个 C++ 服务器 运行ning。然后,在同一台机器上,我想 运行 可以联系该服务器的其他程序,并获取 M
的内存地址。 M
只读,服务器创建一次。我应该能够生成一个客户端 ./test
,并且该程序应该能够对 M
进行只读访问。服务器应始终 运行ning,但我可以随时 运行 其他程序,例如 ./test
。
我不太了解 C++ 或 OS,最好的方法是什么?我应该使用 POSIX 线程吗?矩阵是原始类型(double
、float
等),所有程序都知道它的维度。客户端程序需要整个矩阵,所以我不希望从服务器到客户端的内存复制有延迟,我只想直接共享该指针。我最好的选择是什么?
当然其他程序不能访问矩阵,只要它在"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 以避免任何竞争条件——就像您在多线程场景中所做的那样相同的过程。