我正在使用内核2.6在Linux上编写网络守护程序 一个生产者流程和N个消费者流程,它不会对数据进行任何更改,也不会向生产者创建任何响应。
每当生产者进程生成一个数据对象,其长度从几个10字节变化到几十个K字节时,就必须将数据对象传递给一个可用的消费者进程。
我第一次考虑使用命名/未命名的PIPE。然而, 它们将是内存复制开销。
由于该程序可能与大量具有低延迟的对等端一起工作, 复制开销可能有害。因此,我决定使用POSIX共享内存和mmap()。
我只是想知道使用 POSIX共享内存与mmap()之间的进程之间共享数据是否不会导致任何内存复制,与PIPE不同。
此外,还有其他方法可以在进程之间共享数据,但结果是零拷贝吗? 该程序将在具有最新版本内核的Linux上运行 并且可能没有跨平台能力。
我决定不为每个消费者/产品生成/运行一个线程,而是一个过程 由于设计问题。
感谢您的回复。
答案 0 :(得分: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)
答案 1 :(得分:2)
共享内存不应引入任何副本(缓存一致性除外),您可以直接访问内存,这样您就可以避免代码中的副本。
答案 2 :(得分:0)
是的,它应该是零拷贝。
但是,它也是一种(可能是过早的)优化,您需要非常小心,以确保您的进程与共享内存的分配/释放/修改正确协作。您当然需要某种互斥锁来避免并发访问问题。
我个人会使用管道,直到性能成为一个合适的问题。如果确实如此,建议使用Boost :: Interprocess或类似的库是合理的。