Chapter 15. Threads and related objects

Index

Introduction
Mutex-protected objects
Readers/writer mutex pairs
Mutex objects
Condition variable objects
Readers-writer lock objects
Execution threads
Checking the results of an execution thread
Arguments to run() methods must be copy-constructible
Optional superclasses of thread-executing objects
Running a lambda inside a separate thread
Cleanup thread
Stick a fork() in it: you're done
Thread logging
Timer threads
Using mcguffins to cancel recurring tasks
Weak local thread objects
Local thread singleton objects
Thread worker pools
A simple worker pool thread
Notifying an event file descriptor
Notifying an event queue
Thread-safe semaphores

Introduction

LIBCXX adds x::rwmutex to supplement std::rwmutex and std::condition_variable from the C++ library. This is a lightweight readers/writer design pattern implemented as a pair of TimedLockable classes, with appropriate semantics.

x::mutex, x::cond, and x::rwlock, are full fledged reference-counted objects that implement similar semantics as their C++ library equivalent, except that they are reference-counted objects. A mutex lock gets released when the thread that holds the last reference to a lock goes out of scope, which may not necessarily be the same thread that acquired the lock. The read-write lock is a reference-counted wrapper for x::rwmutex.

These classes implement basic locking functionality. An additional set of templates create formal design patterns that force acquisition of an appropriate lock in order to gain access to a protected object. x::mpobj implements a basic design pattern that forces lock acquisition in order to access and underlying resource in a thread-safe manner. Forgetting to acquire a mutex lock, before accessing an object, is a common source of difficult bugs. x::mpobj enforces lock acquisition. Access to the object requires obtaining a lock structure that's typically short-lived, so this is not a reference-counted object. x::mpcobj supplements x::mpobj with a condition variable.

The next step up is the x::sipobj template that defines somewhat important objects, which demand proper locking rights from a x::rwmutex, providing two levels of access to the underlying objects. Finally, the x::vipobj template defines very important objects, which extend mere somewhat important objects with a protocol for registering and invoking handlers that notify interested parties anytime the very important object gets changed.

See Appendix A, Porting and compatibility notes for some additional notes on mutex objects.