【问题标题】:Transferring data between executables在可执行文件之间传输数据
【发布时间】:2013-02-07 12:15:34
【问题描述】:

我有两个在 Windows 上用 C++ 编写的可执行文件。我在一个中生成了一些数据,并想调用另一个可执行文件来处理这些数据。我可以将数据写入一个文件,然后在另一个可执行文件中读取它,但这在磁盘 I/O 方面似乎相当昂贵。有什么更好的方法来做到这一点?这似乎是一个很简单的问题,但谷歌却无济于事!

假设数据大约 100MB,并且在需要发送之前完整生成(即不需要流式传输)。

在混合 32 位和 64 位进程时有效的答案会获得加分。

【问题讨论】:

  • 命名管道、本地winsockets、内存映射文件、共享内存、邮件槽、注册表、窗口消息(不适合大数据),还有什么?任你选。如果您告诉我们更多有关数据(大小等)以及您希望共享数据的性质的信息,我们可以就哪种方法最好提供更好的建议。
  • 一般情况下,这叫inter-process communication
  • 当然,我已经添加了一些关于数据的信息。最初我只是写了“大量”,但在发布之前编辑了我的问题,我真的应该给出一些数字:)
  • 您正在寻找的通用术语是进程间通信,我相信谷歌可以提供帮助。或者更具体一点,说明您的目标和要求,以便在此处提供更多技术性答案。

标签: c++ windows process data-sharing


【解决方案1】:

如果您的进程可以轻松地写入和读取文件,请继续。使用CreateFile 创建文件并将其标记为临时和可共享。 Windows 使用此提示来延迟物理写入,但仍遵守所有文件语义。由于您的文件只有 100 MB 并且正在使用中,因此几乎可以肯定 Windows 能够将其内容完全保存在 RAM 中。

【讨论】:

  • 好吧,我不知道这种缓存这么可靠。绝对是最简单的解决方案,谢谢:)
  • 这种缓存与将数据保存在 RAM 中一样可靠。如果需要,Windows 可以将 RAM 分页到交换文件。而在幕后,这实际上是相同的机制。虚拟内存管理器在 RAM 和磁盘上的支持位置之间保持关联。
【解决方案2】:

您可以使用Boost.MPI。它来自具有高质量标准的 Boost,并且代码示例看起来非常明确:

http://www.boost.org/doc/libs/1_53_0/doc/html/mpi/tutorial.html#mpi.point_to_point

// The following program uses two MPI processes to write "Hello, world!"
// to the screen (hello_world.cpp):

int main(int argc, char* argv[])
{
  mpi::environment env(argc, argv);
  mpi::communicator world;

  if (world.rank() == 0) {
    world.send(1, 0, std::string("Hello"));
    std::string msg;
    world.recv(1, 1, msg);
    std::cout << msg << "!" << std::endl;
  } else {
    std::string msg;
    world.recv(0, 0, msg);
    std::cout << msg << ", ";
    std::cout.flush();
    world.send(0, 1, std::string("world"));
  }
  return 0;
}

【讨论】:

  • Boost 从未停止让我惊叹!这似乎是一个不错的选择,特别是如果我将其扩展到多台机器上工作,但现在我将使用 MSalters 建议的依赖文件缓存的更简单的选择。
【解决方案3】:

假设你只想去“一个方向”(也就是说,你不需要从子进程获取数据),你可以使用_popen()。您将数据写入管道,子进程从stdin 读取数据。

如果您需要双向数据流,那么您将需要使用两个管道,一个作为输入,一个作为输出,并且您需要设置子进程如何连接到这些管道的方案 [您仍然可以将标准输入/标准输出设置为数据路径,但您也可以使用一对命名管道]。

第三个选项是shared memory 区域。我从未在 Windows 中这样做过,但其原理与我在 Linux 中使用的原理几乎相同[以及多年前在 OS/2 中使用的原理]: 1. 在父进程中创建一个具有给定名称的内存区域。 2.子进程打开同一个内存区域。 3. 数据由父进程存储,由子进程读取。 4. 如有必要,可以使用信号量或类似信号来表示完成/结果就绪/等。

【讨论】:

  • 我学到了一些新东西 :) 谢谢!管道听起来是个不错的选择,但我猜共享内存意味着共享地址空间,这在混合 32 位和 64 位进程时不起作用。
  • 因为我没试过,不知道,但是我相信只要你使用一个命名的共享内存,并且不要超过32位的地址限制[所以小于2GB],它应该可以工作。请记住不要将指针放在共享内存中。内存不是(不一定)在同一地址共享。
  • 啊对,我误解了代码示例。是的,它看起来确实是这样工作的。谢谢 x2!
  • 在混合 32 位和 64 位时使用 boost::interprocess::managed_windows_shared_memory 对我来说不能正常工作。
猜你喜欢
  • 1970-01-01
  • 2021-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-06
相关资源
最近更新 更多