2011-02-26 149 views
9

我写的网络守护进程,在Linux内核2.6,其中有 一个生产者进程消费者氮处理,不使对数据进行任何改变,而不会产生任何响应回制片人。具有共享内存结果的进程之间进行通信零拷贝?

只要生产者进程生成一个数据对象,其长度从几个10字节到几十K字节不等,就必须将数据对象传递给一个可用的使用者进程。

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

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

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

如果使用过程之间共享数据POSIX共享内存使用mmap()不会导致任何存储器复制,不像PIPE我只是想知道。

另外,是否有任何其他方式来共享进程之间的数据,但结果零拷贝? 该程序将在Linux上运行,最近版本的内核为 ,可能不需要具有跨平台功能。

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

感谢您的回复。

回答

5

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

2

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

0

是的,它应该是零拷贝。

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

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

+4

确定进程之间移动大量数据不是“过早优化”,而是“必要的体系结构”。并不是所有的优化(或设计或架构)都“不成熟”。 – 2013-12-10 01:04:34