2

I have a thread in process 1 create a boost::interprocess::managed_shared_memory segment. In this segment I allocate a boost::interprocess::deque using a custom allocator and I create a boost::interprocess::interprocess_mutex and 2 boost::interprocess::interprocess_condition variables using the default allocator. I use the find_or_construct method to create these.

I have another process (process 2) which opens these using the find method on the boost::interprocess::managed_shared_memory segment which I have opened in process 2.

I understand that managed_shared_memory segments have kernel or filesystem persistency and the interprocess_mutex/interprocess_condition variables have process level persistency.

The scenario where I am getting stuck.

1) Process 1 starts the thread which creates everything.

2) Process 2 starts and opens everything, at this stage the shared memory and synchronization is working well.

3) Process 1 restarts the thread which tries to create everything again (I believe it shouldnt though as I am using find_or_construct)

4) Process 2 is stuck on a wait call for a condition variable even though the thread in Process 1 has done a notify.

Am I missing something in terms of how I should create the shared memory and mutex/conditons or something along the lines of persistence? I am running this code on Windows.

rudasi
  • 185
  • 2
  • 14

1 Answers1

3

Consider using:

boost::interprocess::named_mutex
boost::interprocess::scoped_lock<boost::interprocess::named_mutex>
boost::interprocess::named_condition 

Rather than allocating the mutexes & condition variables in an existing shared memory block. Boost handles a lot of the messy details for you.

Note: that you create these named_* objects in process space, not in shared memory. Boost creates the actual shared memory segments containing the mutex & condition variables for you.

I have also had trouble trying to map a shared memory segment twice into the same process. Is there any chance that when you run the second instance of the Process1 thread that is attempting to create a new mapping while the old one still exists?

Dale Wilson
  • 9,166
  • 3
  • 34
  • 52
  • Im not sure if it is trying to create a new mapping, I would not think so as I would think it would try to open the existing one. Is there a way to check? Initially I had tried using then named_mutex and named_condition variables but ran into problems with condition variables, I posted it on stackoverflow but did not get an answer http://stackoverflow.com/questions/17731050/boost-named-condition-is-not-waking-up-waiting-process . – rudasi Aug 07 '13 at 20:48
  • I looked at your other question and once I understood it (sorry for the noisy comments but I'm doing this in the background while my compiles run, so I missed a few things on my first reading.) I agree that the code there is correct (barring the fact that you create/destroy the mutex and shared memory segment, but not the condition variables) – Dale Wilson Aug 08 '13 at 15:58
  • Hi Dale, I am not sure what the static wrappers do. My understanding though is that the remove method called on the start or exit of the thread should only remove stuff if nothing is connected to it, is that correct? – rudasi Aug 08 '13 at 16:06
  • I have used a named_mutex to protect the constuction of a shared_memory area. (Not managed, I did my own memory allocation) In that area I allocated an object that contained a boost::interprocess::interprocess_mutex and boost::interprocess::interprocess_condition. Used boost::interprocess::scoped_Lock<...> to lock/unlock it. This worked. One difference... – Dale Wilson Aug 08 '13 at 16:08
  • As a general rule I try always to unlock the mutex before notifying the condition. This avoids the case where the sleeping process wakes up and tries to reacquire the mutex, but fails, because the notifying process still has the mutex. (i.e. it often makes one fewer trips through the dispatcher.) – Dale Wilson Aug 08 '13 at 16:10
  • Re remove: On linux, it's like deleting a file. The file system entry to the shared memory segment is gone, so no one can find it, but the old file continues to exist as long as anyone has a handle to it. You can then create a new shared memory segment with the same name. The code you have shown shouldn't encounter this problem, however if one of the procsses exits then restarts (as opposed to just restarting a thread) then yes, you will be in trouble because you will have two shared memory segments rather than one. – Dale Wilson Aug 08 '13 at 16:14
  • But they would be 2 shared memory segments with the same name? – rudasi Aug 08 '13 at 16:24
  • Yep and you would be signaling the condition in the deleted-but-still-accessible old segment while waiting for the condition in the newly-created segment. Try experimenting with linux files: in one console cat >abc and start typing lines. in another console window rm abc and cat new data to abc ending with ^D. Now go back to the first one, add a couple more lines then ^D. See which version of the file survives. Shared memory segments behave the same. – Dale Wilson Aug 08 '13 at 16:32
  • Thanks, ill try that out. I have a quick hack at the moment where I use a global flag which only lets the shared memory be deleted once when the process starts. – rudasi Aug 08 '13 at 16:49