Scoped Locking
We've been using the scoped-locking idiom throughout the first chapter, but it deserves to be treated separately. After all, much multi-threaded programming is still done using more procedural APIs such as POSIX threads (pthreads), in which the programmer must explicitly unlock mutexes.
The Boost.Threads library uses the Resource-Acquisition-Is-Initialisation (RAII) idiom[1] in the implementation of its scoped locks. When you create a scoped_lock object (associated with the mutex you want to acquire) the constructor locks the mutex, and the destructor unlocks the mutex. C++ has deterministic destruction, so the language guarantees that local objects will be destroyed when a scope is exited by any means.
The most obvious benefit of this idiom is that it is now impossible to forget to unlock a mutex. The scoped_lock destructor will be called no matter how or where the function is exited, so we nolonger have to check that all return paths unlock the mutex. This is an especially big win when a function has multiple exit points, or when a maintenance programmer adds a new exit point without fully comprehending the function.
Another important benefit of scoped locking is that we gain a measure of exception safety. When exceptions are thrown local objects are destroyed during stack unwinding, so the scoped_lock will help ensure the function exits in a consistent state.
Arguably, a disadvantage of scoped locking is that it decreases the clarity of your locking strategy since unlocking is implicit rather than explicit.
References
1. Stroustrup, B. (1997). The C++ Programming Language. Adsison-Wesley.
