Search code examples
c++boostboost-thread

Why boost::mutex uses atomic operations and events instead of critical sections


According to the answers from this question last versions of boost::mutex uses atomic operations and a Win32 Event for blocking waits instead of critical sections. Why? What is the reason behind it?


Solution

  • I belive that this what you are looking for (from https://www.justsoftwaresolutions.co.uk/articles/implementing_mutexes.html):

    The simplest way to implement a mutex would be to write a wrapper class for one of the native Windows synchronization objects; after all, that's what they're there for. Unfortunately, they all have their problems. The Mutex, Event and Semaphore are kernel objects, so every synchronization call requires a context switch to the kernel. This can be rather expensive, especially so when there is no contention.

    Boost mutexes are only designed for use within a single process, so the CRITICAL_SECTION looks appealing. Unfortunately, there are problems with this, too. The first of these is that it requires explicit initialization, which means it cannot reliably be used as part of an object with static storage duration — the standard static-initialization-order problem is compounded by the potential of race conditions, especially if the mutex is used as a local static. On most compilers, dynamic initialization of objects with static storage duration is not thread-safe, so two threads may race to run the initialization, potentially leading to the initialization being run twice, or one thread proceding without waiting for the initialization being run by the other thread to complete. The second problem is that you can't do a timed wait on a CRITICAL_SECTION, which means we need another solution for a mutex that supports timed waits, anyway.

    There is also another problem with using CRITICAL_SECTIONs as a high-performance mutex, which is that a thread unlocking the CRITICAL_SECTION will hand-off ownership to a waiting thread.