Table of contents : Table of Contents Reader Testimonials Introduction Conventions Special Fonts Special Symbols Special Boxes Source Code Run the Programs How should you read the book? Personal Notes Acknowledgment About Me A Quick Overview Concurrency with Modern C++ C++11 and C++14: The Foundation Memory Model Multithreading C++17: Parallel Algorithms of the Standard Template Library Execution Policy New Algorithms Coroutines Case Studies Calculating the Sum of a Vector The Dining Philosophers Problem by Andre Adrian Thread-Safe Initialization of a Singleton Ongoing Optimization with CppMem Fast Synchronization of Threads Variations of Futures Modification and Generalization of a Generator Various Job Workflows The Future of C++ Executors Extended futures Transactional Memory Task Blocks Data-Parallel Vector Library Patterns and Best Practices Synchronization Concurrent Architecture Best Practices Data Structures Challenges Time Library CppMem Glossary The Details Memory Model Basics of the Memory Model What is a memory location? What happens if two threads access the same memory location? The Contract The Foundation The Challenges Atomics Strong versus Weak Memory Model The Atomic Flag std::atomic All Atomic Operations Free Atomic Functions std::atomic_ref (C++20) The Synchronization and Ordering Constraints The Six Variants of Memory Orderings in C++ Sequential Consistency Acquire-Release Semantic std::memory_order_consume Relaxed Semantics Fences std::atomic_thread_fence std::atomic_signal_fence Multithreading The Basic Thread std::thread Thread Creation Thread Lifetime Thread Arguments Member Functions The Improved Thread std::jthread (C++20) Automatically Joining Cooperative Interruption of a std::jthread Shared Data Mutexes Locks std::lock Thread-safe Initialization Thread-Local Data Condition Variables The Predicate Lost Wakeup and Spurious Wakeup The Wait Workflow Cooperative Interruption (C++20) std::stop_source std::stop_token std::stop_callback A General Mechanism to Send Signals Additional Functionality of std::jthread New wait Overloads for the condition_variable_any Semaphores (C++20) Latches and Barriers (C++20) std::latch std::barrier Tasks Tasks versus Threads std::async std::packaged_task std::promise and std::future std::shared_future Exceptions Notifications Synchronized Outputstreams (C++20) Parallel Algorithms of the Standard Template Library Execution Policies Parallel and Vectorized Execution Exceptions Hazards of Data Races and Deadlocks Algorithms The New Algorithms More overloads The functional Heritage Compiler Support Microsoft Visual Compiler GCC Compiler Further Implementations of the Parallel STL Performance Microsoft Visual Compiler GCC Compiler Coroutines (C++20) A Generator Function Characteristics Typical Use Cases Underlying Concepts Design Goals Becoming a Coroutine The Framework Promise Object Coroutine Handle Coroutine Frame Awaitables and Awaiters Awaitables The Concept Awaiter std::suspend_always and std::suspend_never initial_suspend final_suspend Awaiter The Workflows The Promise Workflow The Awaiter Workflow co_return A Future co_yield An Infinite Data Stream co_await Starting a Job on Request Thread Synchronization std::generator (C++23) Case Studies Calculating the Sum of a Vector Single-Threaded addition of a Vector Multi-threaded Summation with a Shared Variable Thread-Local Summation Summation of a Vector: The Conclusion The Dining Philosophers Problem by Andre Adrian Multiple Resource Use Multiple Resource Use with Logging Erroneous Busy Waiting without Resource Hierarchy Erroneous Busy Waiting with Resource Hierarchy Still Erroneous Busy Waiting with Resource Hierarchy Correct Busy Waiting with Resource Hierarchy Good low CPU load Busy Waiting with Resource Hierarchy std::mutex with Resource Hierarchy std::lock_guard with Resource Hierarchy std::lock_guard and Synchronized Output with Resource Hierarchy std::lock_guard and Synchronized Output with Resource Hierarchy and a count A std::unique_lock using deferred locking A std::scoped_lock with Resource Hierarchy The Original Dining Philosophers Problem using Semaphores A C++20 Compatible Semaphore Thread-Safe Initialization of a Singleton Double-Checked Locking Pattern Performance Measurement Thread-Safe Meyers Singleton std::lock_guard std::call_once with std::once_flag Atomics Performance Numbers of the various Thread-Safe Singleton Implementations Ongoing Optimization with CppMem CppMem: Non-Atomic Variables CppMem: Locks CppMem: Atomics with Sequential Consistency CppMem: Atomics with Acquire-Release Semantics CppMem: Atomics with Non-atomics CppMem: Atomics with Relaxed Semantic Conclusion Fast Synchronization of Threads Condition Variables std::atomic_flag std::atomic Semaphores All Numbers Variations of Futures A Lazy Future Execution on Another Thread Modification and Generalization of a Generator Modifications Generalization Various Job Workflows The Transparent Awaiter Workflow Automatically Resuming the Awaiter Automatically Resuming the Awaiter on a Separate Thread Thread-Safe Queue The Future of C++ Executors A long Way What is an Executor? First Examples Goals of an Executor Concept Terminology Execution Functions A Prototype Implementation Extended Futures Concurrency TS v1 Unified Futures Transactional Memory ACI(D) Synchronized and Atomic Blocks transaction_safe versus transaction_unsafe Code Task Blocks Fork and Join define_task_block versus define_task_block_restore_thread The Interface The Scheduler Data-Parallel Vector Library Data-Parallel Vectors The Interface of the Data-Parallel Vectors Patterns Patterns and Best Practices History Invaluable Value Pattern versus Best Practices Anti-Pattern Synchronization Patterns Dealing with Sharing Copied Value Thread-Specific Storage Future Dealing with Mutation Scoped Locking Strategized Locking Thread-Safe Interface Guarded Suspension Concurrent Architecture Active Object Challenges Solution Components Dynamic Behavior Advantages and Disadvantages Implementation Monitor Object Challenges Solution Components Dynamic Behavior Advantages and Disadvantages Implementation Half-Sync/Half-Async Challenges Solution Components Dynamic Behavior Advantages and Disadvantages Example Reactor Challenges Solution Components Dynamic Behavior Advantages and Disadvantages Example Proactor Challenges Solution Components Advantages and Disadvantages Example Further Information Best Practices General Code Reviews Minimize Sharing of Mutable Data Minimize Waiting Prefer Immutable Data Use pure functions Look for the Right Abstraction Use Static Code Analysis Tools Use Dynamic Enforcement Tools Multithreading Threads Data Sharing Condition Variables Promises and Futures Memory Model Don't use volatile for synchronization Don't program Lock Free If you program Lock-Free, use well-established patterns Don't build your abstraction, use guarantees of the language Don't reinvent the wheel Data Structures General Considerations Concurrent Stack Locking Strategy Granularity of the Interface Typical Usage Pattern Linux (GCC) Windows (cl.exe) Avoidance of Loopholes Contention Single-Threaded Summation without Synchronization Single-Threaded Summation with Synchronization (lock) Single-Threaded Summation with Synchronization (atomic) The Comparison Scalability Invariants Exceptions Lock-Based Data Structures Concurrent Stack A Stack Concurrent Queue A Queue Coarse-Grained Locking Fine-Grained Locking Lock-Free Data Structures General Considerations The Next Evolutionary Step Sequential Consistency Concurrent Stack A Simplified Implementation A Complete Implementation Concurrent Queue Further Information Challenges ABA Problem Blocking Issues Breaking of Program Invariants Data Races Deadlocks False Sharing Lifetime Issues of Variables Moving Threads Race Conditions The Time Library The Interplay of Time Point, Time Duration, and Clock Time Point From Time Point to Calendar Time Cross the valid Time Range Time Duration Calculations Clocks Accuracy and Steadiness Epoch Sleep and Wait CppMem - An Overview The simplified Overview 1. Model 2. Program 3. Display Relations 4. Display Layout 5. Model Predicates The Examples Glossary adress_free ACID CAS Callable Unit Complexity Concepts Concurrency Critical Section Deadlock Eager Evaluation Executor Function Objects Lambda Functions Lazy evaluation Lock-free Lock-based Lost Wakeup Math Laws Memory Location Memory Model Modification Order Monad Non-blocking obstruction-free Parallelism Predicate Pattern RAII Release Sequence Sequential Consistency Sequence Point Spurious Wakeup Thread Total order TriviallyCopyable Undefined Behavior volatile wait-free Index