4
votes

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.

1

1 Answers

0
votes

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!