I am building a multi-producer/single-consumer application using IPC, implemented using Boost.Interprocess.
Each producer sends a message by allocating a block inside shared memory (managed_shared_memory::allocate), and marshalling an object into that block. Then, it sends a small object via a message_queue which holds the location (offset) of the block and the size.
The consumer receives this indicator from the queue and unmarshalls the object. The consumer is responsible for deallocating the block of memory.
Based on this implementation, I don’t believe the objects or blocks as they exist in memory need synchronisation, because as soon as the consumer knows about them, the producer will no longer touch them. Therefore, I believe it is only the internals of message_queue and managed_shared_memory which need synchronisation.
My question is: Bearing in mind that each process is single-threaded, do allocate/deallocate, and send/receive calls need synchronisation?
The Boost examples provided by the documentation don’t make use of synchronisation for the message queue, but I think this is only to simplify the sample source.
I have seen this question, but it is asking about thread-safety, and not about these specific components of Boost.Interprocess.
You do not need to use any kind of locking to protect these, operations. They are already protected using a recursive mutex in shared memory, otherwise multiple processes would not be able to operate in the same shared memory block at the same time.
Regarding managed_shared_memory:
This also extends to raw allocation, you can verify this by looking at
boost/interprocess/mem_algo/detail/simple_seq_fit.hpp.For message queue,
boost::interprocessconsiders this to be a synchronization mechanism in the same way a mutex is, it will take care of all the necessary guarantees, locking its internal datastructures and issuing memory barriers as required.Furthermore this is all equally applicable to multithreaded programming. Even if you were calling send or allocate from multiple threads in the same program everything would be fine. The locking
boost::interporcessprovides would protect you from other threads in the same way it protects you from other processes.