5

I have a managed shared memory segment which has a boost::interprocess::interprocess_mutex and a boost::interprocess::interprocess_condition variable. I have 2 processes accessing the shared memory and they are synchronizing access based on the mutex and condition. I have come across a case where my first process blocks on notify_all method, initially I thought this was a non blocking method but it seems the interprocess condition implements a mutex which is used to synchronize itself.

The case where I get this deadlock is when process 2 is killed ungracefully while it is waiting on the condition, this I believe prevents the conditions mutex from being unlocked and then when I run process 2 again it blocks. Is there anyway to reset or clean up the interprocess condition the second time I start process 2.

rudasi
  • 185
  • 2
  • 14

1 Answers1

0

http://www.boost.org/doc/libs/1_48_0/boost/interprocess/sync/interprocess_mutex.hpp

Are you using timed lock?

For a simple dead-lock avoidance algorithm take a look here: Wikipedia
It's for threads but I believe it can be used with interprocess_locks.

Recursively, only one thread is allowed to pass through a lock. If other threads enter the lock, they must wait until the initial thread that passed through completes n number of times. But if the number of threads that enter locking equal the number that are locked, assign one thread as the super-thread, and only allow it to run (tracking the number of times it enters/exits locking) until it completes. After a super-thread is finished, the condition changes back to using the logic from the recursive lock, and the exiting super-thread

  • sets itself as not being a super-thread

  • notifies the locker that other locked, waiting threads need to re-check this condition

If a deadlock scenario exists, set a new super-thread and follow that logic. Otherwise, resume regular locking.

Note that the above algorithm doesn't solve livelock situations, to prevent such behaviour use a semaphore if possible.

I was stunned to notice that interprocess_mutex doesn't support implement deadlock avoidance algorithms since these days, most mutex i.e std::mutex and boost::mutex already do. I guess it's OS specific limitations.

For more flexibility try using a named_upgradable_mutex

Use a timed lock catch the exception when the process crashes and remove the upgradable mutex!. This type also allows elevated priviledges to be obtained by either thread!

gifnoc-gkp
  • 1,506
  • 1
  • 8
  • 17
  • I am using regular locks. It wont work in this case I think as when Process 2 crashes it is happens to be in wait on condition case so the synchronization mutex has been unlocked, but the number of waiters in the condition variable is set to 1 and the conditions local mutex is locked. When Process 1 runs and does a notify_all its see that the conditions mutex is still set and gets blocked on the notify_all. I need a way to clean up this condition when I happen to get a sudden crash of process 2, either by knowing it crashed and cleaning it up when I restart it or some other way. – rudasi Aug 14 '13 at 20:38
  • @rudasi Check again :) – gifnoc-gkp Aug 14 '13 at 20:45
  • I cant use timed locks as I running time critical stuff, as soon as process 2 crashes I need to reset the state of the condition so process 1 does not block. Im thinking of using a windows mutex to check if process 2 has crashed. – rudasi Aug 14 '13 at 20:50
  • Also I have had issues with boost named_mutex and named_conditions, http://stackoverflow.com/questions/17731050/boost-named-condition-is-not-waking-up-waiting-process – rudasi Aug 14 '13 at 20:51