IPC 通过两个不同的可执行文件?

Posted

技术标签:

【中文标题】IPC 通过两个不同的可执行文件?【英文标题】:IPC through two different executables? 【发布时间】:2013-12-12 19:47:54 【问题描述】:

我有以下问题,我知道我需要通过共享内存或网络套接字使用 IPC。

我有一个用 VS2010 编译的可执行文件(意味着一个单独的 .exe),它从某个地方获取数据,它应该使该数据可用于第二个可执行文件。

boost::interprocess::managed_shared_memory managed_shm(
    boost::interprocess::open_or_create,
    "MyMemBlock",
    4000000);

第二个可执行文件是用 VS2012 编译的,应该接收该数据(或从内存中获取)并处理它。

// fails with a boost::interprocess::interprocess_exception
boost::interprocess::managed_shared_memory managed_shm(
    boost::interprocess::open_only,
    "MyMemBlock");

整个过程需要尽可能快。 使用相同的 Visual Studio 版本编译两个可执行文件不是一种选择,一个代码库仅使用 VS2010 编译,另一个仅使用 VS2012/2013 编译。

但是,我第一次尝试使用 boost::interprocess 没有用(第二个进程抛出 boost::interprocess::interprocess_exception),我不完全理解内存是如何共享的,或者更准确地说,共享内存信息如何从一个进程传递到另一个进程。第一个exe如何填充共享内存块的信息?它是否仅适用于 one 可执行文件中的多个进程?不是多个.exe?它是否必须是两个可执行文件使用的相同 boost DLL?我唯一的选择是 IPC via Sockets 吗?

【问题讨论】:

你的整个问题描述由两个词组成,“没用”。 (顺便说一句,最常见的共享内存程序是让一个进程在共享内存中存储一​​个普通指针,然后让另一个进程尝试取消引用它。很容易在没有意识到的情况下做到这一点。例如,你可以' t 将std::string 存储在共享内存中,因为它会这样做。) @DavidSchwartz 我在该函数抛出的第二个代码块中提到。不过,您必须向右滚动很多才能看到它。我更新了问题以使其更清楚。不过,我的主要问题是,这个共享内存 IPC 是否可以使用 2 个不同的可执行文件,这些可执行文件是用 2 个不同的 boost DLL 编译的。因为我无法想象第二个进程怎么可能找到第一个进程的内存。我能找到的所有示例都使用 one 生成两个不同进程的可执行文件。 我认为不同的 boost DLL 应该无关紧要,但是您的数据在共享内存中的结构方式肯定会。您不应尝试共享任何二进制数据结构,而应仅共享普通的可序列化数据或原始数据类型。 两个应用程序都有管理员权限吗?如果没有,试试吧! 实际上,我得到了它的工作。直到,你让我思考——我都尝试了管理员权限,但没有任何区别。但实际上一个应用程序使用的是 boost 1.53,另一个是 1.55。然后我在两者上都尝试了 1.53 - 繁荣,它奏效了。所以我真正的问题得到了我自己的回答,因为它有效:是的,IPC 不仅适用于 1 个可执行文件中的 2 个进程,而且适用于 2 个使用不同编译器、不同 libc、不同 boost DLL 的不同可执行文件,但它们必须使用相同的提升版本 【参考方案1】:

IPC 适用于两个不同的可执行文件。访问共享内存的两个进程不需要编译成同一个可执行文件。事实上,它们可以用不同版本的 Visual Studio 和不同的 boost DLL 编译。但是,必须在两个可执行文件中使用相同的版本 boost。

非常有趣的是,同样不起作用的是,在 release-build 中运行一个可执行文件,在 debug-build 中运行另一个可执行文件。我猜他们以完全不同的方式分配内存并且不能共享它。

【讨论】:

【参考方案2】:

您可以尝试原生 Windows IPC。有很多你可以google them。我推荐Memory-mapped files。这里还有来自MS的好文章

这是非持久内存映射文件的示例场景。

1. Process A creates the memory-mapped file and writes a value to it.

2. Process B opens the memory-mapped file and writes a value to it.

3. Process C opens the memory-mapped file and writes a value to it.

4. Process A reads and displays the values from the memory-mapped file.

5. After Process A is finished with the memory-mapped file, the file is 
   immediately reclaimed by garbage collection.

取自here

Boost 还有implementation of memory-mapped files,它会根据编译目标平台使用原生低级API。示例代码可取here

【讨论】:

内存映射文件确实是一个非常简单的解决方案。 它应该是跨平台的。而且我怀疑这将与我尝试使用 boost ipc 时遇到相同的问题:它可以与使用 2 个不同的库/libc DLL 编译的 2 个不同的可执行文件一起使用吗? 它不是跨平台的。但是你可以试试 Boost 的 boost.org/doc/libs/1_35_0/libs/iostreams/doc/classes/… 内存映射文件既快速又简单!我推荐他们。 感谢大家的帮助。不过我有点误解:我的问题从来不是如何做 IPC 以及不同的方法是什么。我对此很熟悉。这完全是关于 2 个可执行文件和不同的 DLL。但是你在这里给了我一些很好的链接和提示,谢谢!

以上是关于IPC 通过两个不同的可执行文件?的主要内容,如果未能解决你的问题,请参考以下文章

Linux IPC 技术的选择

mmap 的可执行文件可以多次使用吗?

相同的源代码,不同的可执行文件大小?

不同 C 编译器生成的可执行文件的差异

未找到 GraphViz 的可执行文件 - 为啥通过 pip 安装 graphViz 后没有安装可执行文件?

为不同的可执行文件名称制作参数