10

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

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

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

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

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

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

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

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

谢谢您的回复。

4

3 回答 3

6

共享内存通常专门设计为不会导致复制开销(来源: 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

于 2011-02-27T00:00:54.993 回答
2

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

于 2011-02-26T23:53:32.423 回答
0

是的,它应该是零拷贝。

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

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

于 2011-02-27T08:11:53.420 回答