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 通过两个不同的可执行文件?的主要内容,如果未能解决你的问题,请参考以下文章