3

我正在使用 IPC 构建一个多生产者/单消费者应用程序,使用Boost.Interprocess实现。

每个生产者通过在共享内存 () 中分配一个块managed_shared_memory::allocate并将一个对象编组到该块中来发送消息。然后,它通过 a 发送一个小对象,该对象message_queue保存块的位置(偏移量)和大小。

消费者receives从队列中取出这个指示符并解组对象。消费者负责释放内存块。

基于这个实现,我不相信内存中存在的对象或块需要同步,因为一旦消费者知道它们,生产者将不再接触它们。因此,我相信只有内部message_queue结构managed_shared_memory需要同步。

我的问题是:记住每个进程都是单线程的,做allocate/deallocatesend/receive调用需要同步吗?

文档提供的 Boost 示例没有使用消息队列的同步,但我认为这只是为了简化示例源。


我见过这个问题,但它询问的是线程安全,而不是 Boost.Interprocess 的这些特定组件。

4

1 回答 1

6

您不需要使用任何类型的锁定来保护这些操作。它们已经在共享内存中使用递归互斥锁进行保护,否则多个进程将无法同时在同一个共享内存块中操作。

关于managed_shared_memory

命名/唯一分配/搜索/破坏的特征之一是它们是原子的。命名分配使用由内存分配算法模板参数 ( ) 定义的内部 mutex_family typedef 定义的递归同步方案MemoryAlgorithm。也就是说,用于同步命名/唯一分配的互斥锁类型由 MemoryAlgorithm::mutex_family::recursive_mutex_type类型定义。对于共享内存和基于内存映射文件的托管段,此递归互斥锁定义为boost::interprocess::interprocess_recursive_mutex.

这也扩展到原始分配,您可以通过查看boost/interprocess/mem_algo/detail/simple_seq_fit.hpp.

对于消息队列,boost::interprocess将其视为与互斥锁相同的同步机制,它将处理所有必要的保证,锁定其内部数据结构并根据需要发出内存屏障。

此外,这同样适用于多线程编程。即使您在同一个程序中从多个线程调用 send 或 allocate ,一切都会好起来的。锁定boost::interporcess提供将保护您免受其他线程的侵害,就像它保护您免受其他进程的侵害一样。

于 2012-08-14T07:47:41.270 回答