On 15/02/2017 18:42, Phil Endecott via Boost wrote:
Dear Experts,
I've just been surprised by the behaviour of the interprocess mutex and condition variable on abnormal process termination, i.e. they are not automatically released.
Google tells me that I'm not the first to be surprised by this; there have been previous posts here, stack overflow questions etc.
One often-valid observation is that if a process crashes - or otherwise terminates without executing its destructors - while it holds a lock on a shared data structure then the data is probably now corrupt, so unlocking the mutex that protects it is not very useful. I think there is an important case where that does not apply - when the process that crashes is only reading the shared data. In my case, I had written a "monitor" utility that loops forever, waiting on a shared condition, taking the corresponding mutex, and then dumping the shared data to stdout. I had been running this and stopping it by pressing ctrl-C and it had not occurred to me that this might not work as I expected. My attempt at debugging using this utility was making my problems worse, not better! Modifying this code to run destructors on ctrl-C is non-trivial.
There is a very poor but effective workaround if your application can support long delays. Search for BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING and BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS. It's not documented, but it should be added.
I am aware that the SysV shared semaphore is able to undo on process termination (see SEM_UNDO in man semop), and I had assumed that Boost.Interprocess was using this or something like it. I now see that it is using pthreads, which I didn't even realise could work between processes, and I don't think this API has any way to specify process termination behaviour.
Yes, but SysV shared semaphroes can't be placed in shared memory.
Anyway, I'd like to suggest that the interprocess docs should make some mention of the behaviour of the synchronisation primitives on process termination, e.g. somewhere near the beginning of http://www.boost.org/doc/libs/1_63_0/doc/html/interprocess/synchronization_m...
Good suggestion.
I may now try to implement some primitives that use semop() and unlock automatically. I haven't yet looked at what's involved to implement a condition variable on top of a semaphore, so I may not get very far! Has anyone else ever tried this?
There are several algorithms, but the problem is placing them in shared memory. See an adapter in: C:\Data\Libs\boost\boost\interprocess\sync\detail\condition_algorithm_8a.hpp
Also, I note that Interprocess is using "old style" times, not std::chrono like the std::mutex/condition do. Are there any plans to update this?
Yes, but I really can't get time to implement it. The idea one would support std::chrono and boost::chrono. Patches welcome ;-) Best, Ion