【问题标题】:communicating between processes with shared-memory results zero-copy?在共享内存结果零拷贝的进程之间进行通信?
【发布时间】:2023-05-03 23:48:02
【问题描述】:

我正在用内核 2.6 在 Linux 上编写一个网络守护程序,它有 一个生产者进程和N个消费者进程,不会对数据进行任何更改,也不会对生产者产生任何响应。

每当生产者进程产生一个数据对象,其长度从几个 10 字节到几个 10 K 字节不等,它必须将数据对象传递给一个可用的消费者进程。

第一次,我考虑使用命名/未命名的 PIPE。然而, 它们将是内存复制开销。

  1. 生产者的用户空间缓冲区 --copy--> 内核空间 PIPE 缓冲区
  2. 内核空间 PIPE 缓冲区 --copy--> 消费者的用户空间缓冲区

由于该程序可能会以低延迟与大量对等点一起工作, 复制开销可能是有害的。因此,我决定将 POSIX 共享内存与 mmap() 一起使用。

我只是想知道,与 PIPE 不同,使用 POSIX 共享内存和 mmap() 在进程之间共享数据是否不会导致任何内存复制

另外,有没有其他方法可以在进程之间共享数据,但结果是零拷贝? 该程序将在具有最新版本内核的 Linux 上运行 并且可能不必具备跨平台能力。

我决定不为每个消费者/生产者生成/运行一个线程,而是一个进程 由于设计问题。

感谢回复。

【问题讨论】:

    标签: linux ipc shared-memory mmap zero-copy


    【解决方案1】:

    共享内存不应引入任何副本(缓存一致性除外),您可以直接访问内存,这样您就可以避免代码中的副本。

    【讨论】:

      【解决方案2】:

      共享内存通常专门设计为不会导致复制开销(来源:http://www.boost.org/doc/libs/1_46_0/doc/html/interprocess/sharedmemorybetweenprocesses.html#interprocess.sharedmemorybetweenprocesses.sharedmemory.shared_memory_what_is)。

      如果您使用 C++,Boost::Interprocess 是一个很棒的库,可以跨平台实现您所描述的内容——您可以使用它们的共享内存类和 named_upgradable_mutex。 named_upgradable_mutex 类支持在资源上提供独占和可共享锁,因此您可以使用它轻松实现您的消费者-生产者模型。 (来源:http://www.boost.org/doc/libs/1_37_0/doc/html/boost/interprocess/named_upgradable_mutex.html#id2913393-bb

      【讨论】:

        【解决方案3】:

        是的,它应该是零拷贝。

        但是,这也是一种(可能为时过早的)优化,您需要格外小心,以确保您的进程与共享内存的分配/解除分配/修改正确配合。您当然需要某种互斥锁来避免并发访问问题。

        我个人会使用管道,直到性能成为一个适当的问题。如果确实如此,那么使用 Boost::Interprocess 或类似库的建议是合理的。

        【讨论】:

        • 决定在进程之间移动多少数据不是“过早的优化”,而是“必要的架构”。并非所有优化(或设计或架构)都“为时过早”。
        最近更新 更多