如何在不重复的情况下在进程之间共享大量数据? (IPC)

Posted

技术标签:

【中文标题】如何在不重复的情况下在进程之间共享大量数据? (IPC)【英文标题】:How can I share a large array of data between processes without duplicating? (IPC) 【发布时间】:2020-05-28 05:24:57 【问题描述】:

我有一个进程每秒向某个 API 发出一个 http get 请求。然后,此过程对从请求返回的 JSON 字符串进行某种处理。同时,我想把这个 JSON 字符串传递给另一个进程做其他事情。

一个关键点是我想继续将每个新的 JSON 字符串附加到数组的末尾,以便在程序执行期间所有 JSON 字符串都保存在内存中。

我正在研究使用管道或 mmap 来共享 JSON 字符串,因为这些似乎是我所知道的最快的方式。但是,管道似乎会做比必要的工作更多的工作,因为我将不得不发送似乎不必要的字符串,因为它们已经在内存中。

我认为如果我可以将数组映射到两个进程,mmap 就可以避免这个问题。我不希望将字符串写入磁盘上的真实文件,因此我将不得不使用匿名映射,但似乎匿名映射会创建一个归零的区域,然后我必须将我的数组复制到映射的内存中区域共享数据。这似乎也是不必要的工作,因为我在复制内存。

有没有一种方法可以让第二个进程访问字符串数组而不复制字符串或复制?即使线程可以轻松共享内存,我也不能使用线程,因为发出 REST 请求的进程将是 C++ 程序,而第二个进程将是 Python 程序。

【问题讨论】:

当你说“大”是什么意思?几千字节?数百千字节?兆字节? 至于你的问题,inter-process communication 有很多方法,有些(如共享内存)可以在不复制数据的情况下工作。但是,您确实需要某种同步和互锁机制才能使共享内存正常工作。 @Someprogrammerdude 该数组将在程序终止时达到几千兆字节。另外, mmap 不是共享内存吗?我的印象是人们使用 mmap 来共享内存。 您可以使用mmap 将共享内存段映射到您的进程中,但需要围绕它进行一些其他工作才能创建或加载实际的共享内存分割。有很多关于如何做到这一点的教程。 @Someprogrammerdude 我阅读了以下关于共享内存的帖子,并且接受的答案似乎暗示 mmap 是共享内存的现代方式,而 linux 中以“shm”开头的共享内存函数似乎是旧的做事方式。 ***.com/questions/5656530/… 【参考方案1】:

看看boost interprocess

您需要创建一个内存映射文件,将其传递给boost.interprocess allocator。此分配器占用内存映射文件的块。然后可以像使用 std::allocator 返回的一样使用它们。应用了映射,以便内存与进程内特定内存兼容。

boost.interprocess 容器将使用分配器返回的内存。它有一个类似 std::container 的接口。

您需要同步数据。这是通过一些进程间互斥锁完成的,应该用于防止数据访问竞争条件。

另外,消息传递接口 (MPI) 是一种在进程之间进行通信的技术。这通常用于大型计算,例如车祸模拟等。

使用MPI 可以启动多个进程,这些进程通常使用不同的输入数据计算相同的东西。

MPI 提供了创建MPI Window 的可能性。借助此窗口,您可以写入其他MPI 进程的内存。

因此,您的问题的答案是肯定的。但它带来了相当多的成本。 MPI 场景需要流程的启动器。您可能会遇到死锁、数据竞争……

【讨论】:

以上是关于如何在不重复的情况下在进程之间共享大量数据? (IPC)的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 &nbsp 的情况下在行内元素之间添加空格 [重复]

如何在不换行的情况下在引导列之间添加边距[重复]

如何在不知道维度的情况下在 C++ 中传递二维数组 [重复]

如何在不使用临时文件的情况下在 python 的 tarfile 中写入大量数据

如何在不复制的情况下在多个进程中使用大型数据集?

如何在不使用单例的情况下在多个视图控制器之间传递数据?