Share E-Book

Concurrency with Modern C++ What every professional C++ programmer should know about concurrency. (Rainer Grimm)(Z-Library)

Author

Rating No ratings yet

Log in to rate

C++
Language English

C++11 is the first C++ standard that deals with concurrency. The story goes on with C++17, C++20, and will continue with C++23. I'll give you a detailed insight into the current and the upcoming concurrency in C++. This insight includes the theory and a lot of practice C++11 and C++14 have the basic building blocks for creating concurrent or parallel programs. With C++17, we got the parallel algorithms of the Standard Template Library (STL). That means most of the algorithms of the STL can be executed sequentially, in parallel, or vectorized. The concurrency story in C++ goes on. With C++20, we got coroutines, atomic smart pointers, semaphores, latches, and barriers. C++23 supports the first concrete coroutine: std::generator. With future C++ standards, we can hope for executors, extended futures, transactional memory, and more. This book explains the details of concurrency in modern C++ and gives you nearly 200 running code examples. Therefore, you can combine theory with practice and get the most out of it. Because this book is about concurrency, I present many pitfalls and show you how to overcome them. The book is 100 % finished, but I will update it regularly. The next update is probably about C++26. Furthermore, I will write about lock-free concurrent data structure and patterns for parallelization.

Format PDF
Size 12.3 MB
7
Views
(First 20 pages)

Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Page 1
(This page has no text content)
Page 2
Concurrency with Modern C++ What every professional C++ programmer should know about concurrency. Rainer Grimm This book is for sale at http://leanpub.com/concurrencywithmodernc This version was published on 2024-01-20 This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2017 - 2024 Rainer Grimm
Page 3
Tweet This Book! Please help Rainer Grimm by spreading the word about this book on Twitter! The suggested hashtag for this book is #rainer_grimm. Find out what other people are saying about the book by clicking on this link to search for this hashtag on Twitter: #rainer_grimm
Page 4
Contents Reader Testimonials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Special Fonts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Special Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii Special Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv Run the Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv How should you read the book? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v Personal Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v Acknowledgment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . v About Me . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vi A Quick Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1. Concurrency with Modern C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1 C++11 and C++14: The Foundation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.1 Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.2 Multithreading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 C++17: Parallel Algorithms of the Standard Template Library . . . . . . . . . . . . . 8 1.2.1 Execution Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.2.2 New Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.3 Coroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.4 Case Studies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.1 Calculating the Sum of a Vector . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.4.2 The Dining Philosophers Problem by Andre Adrian . . . . . . . . . . . . . . 10 1.4.3 Thread-Safe Initialization of a Singleton . . . . . . . . . . . . . . . . . . . . 10 1.4.4 Ongoing Optimization with CppMem . . . . . . . . . . . . . . . . . . . . . 10 1.4.5 Fast Synchronization of Threads . . . . . . . . . . . . . . . . . . . . . . . . 10 1.5 Variations of Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.6 Modification and Generalization of a Generator . . . . . . . . . . . . . . . . . . . . . 11
Page 5
CONTENTS 1.7 Various Job Workflows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.8 The Future of C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.8.1 Executors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.8.2 Extended futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.8.3 Transactional Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.8.4 Task Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.8.5 Data-Parallel Vector Library . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.9 Patterns and Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.9.1 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.9.2 Concurrent Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.9.3 Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.10 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.11 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.12 Time Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.13 CppMem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.14 Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 The Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2. Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.1 Basics of the Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.1.1 What is a memory location? . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.1.2 What happens if two threads access the same memory location? . . . . . . . 19 2.2 The Contract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.2.1 The Foundation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.2.2 The Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.3 Atomics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.3.1 Strong versus Weak Memory Model . . . . . . . . . . . . . . . . . . . . . . 23 2.3.2 The Atomic Flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.3.3 std::atomic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 2.3.4 All Atomic Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 2.3.5 Free Atomic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 2.3.6 std::atomic_ref (C++20) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 2.4 The Synchronization and Ordering Constraints . . . . . . . . . . . . . . . . . . . . . 67 2.4.1 The Six Variants of Memory Orderings in C++ . . . . . . . . . . . . . . . . 67 2.4.2 Sequential Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 2.4.3 Acquire-Release Semantic . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 2.4.4 std::memory_order_consume . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 2.4.5 Relaxed Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 2.5 Fences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 2.5.1 std::atomic_thread_fence . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 2.5.2 std::atomic_signal_fence . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
Page 6
CONTENTS 3. Multithreading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 3.1 The Basic Thread std::thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 3.1.1 Thread Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 3.1.2 Thread Lifetime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 3.1.3 Thread Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 3.1.4 Member Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 3.2 The Improved Thread std::jthread (C++20) . . . . . . . . . . . . . . . . . . . . . . . 116 3.2.1 Automatically Joining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 3.2.2 Cooperative Interruption of a std::jthread . . . . . . . . . . . . . . . . . . 119 3.3 Shared Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 3.3.1 Mutexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 3.3.2 Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 3.3.3 std::lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 3.3.4 Thread-safe Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 3.4 Thread-Local Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 3.5 Condition Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 3.5.1 The Predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 3.5.2 Lost Wakeup and Spurious Wakeup . . . . . . . . . . . . . . . . . . . . . . . 157 3.5.3 The Wait Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157 3.6 Cooperative Interruption (C++20) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 3.6.1 std::stop_source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 3.6.2 std::stop_token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 3.6.3 std::stop_callback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 3.6.4 A General Mechanism to Send Signals . . . . . . . . . . . . . . . . . . . . . 165 3.6.5 Additional Functionality of std::jthread . . . . . . . . . . . . . . . . . . . 168 3.6.6 New wait Overloads for the condition_variable_any . . . . . . . . . . . . . 169 3.7 Semaphores (C++20) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 3.8 Latches and Barriers (C++20) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 3.8.1 std::latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 3.8.2 std::barrier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 3.9 Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 3.9.1 Tasks versus Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 3.9.2 std::async . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 3.9.3 std::packaged_task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 3.9.4 std::promise and std::future . . . . . . . . . . . . . . . . . . . . . . . . . 199 3.9.5 std::shared_future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 3.9.6 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 3.9.7 Notifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211 3.10 Synchronized Outputstreams (C++20) . . . . . . . . . . . . . . . . . . . . . . . . . . 215 4. Parallel Algorithms of the Standard Template Library . . . . . . . . . . . . . . . . . . . 225 4.1 Execution Policies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 4.1.1 Parallel and Vectorized Execution . . . . . . . . . . . . . . . . . . . . . . . . 228
Page 7
CONTENTS 4.1.2 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 4.1.3 Hazards of Data Races and Deadlocks . . . . . . . . . . . . . . . . . . . . . 231 4.2 Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 4.3 The New Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 4.3.1 More overloads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 4.3.2 The functional Heritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 4.4 Compiler Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 4.4.1 Microsoft Visual Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 4.4.2 GCC Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 4.4.3 Further Implementations of the Parallel STL . . . . . . . . . . . . . . . . . . 242 4.5 Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 4.5.1 Microsoft Visual Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 4.5.2 GCC Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 5. Coroutines (C++20) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 5.1 A Generator Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 5.2 Characteristics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 5.2.1 Typical Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 5.2.2 Underlying Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 5.2.3 Design Goals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 5.2.4 Becoming a Coroutine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 5.3 The Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 5.3.1 Promise Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 5.3.2 Coroutine Handle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 5.3.3 Coroutine Frame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 5.4 Awaitables and Awaiters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 5.4.1 Awaitables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 5.4.2 The Concept Awaiter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 5.4.3 std::suspend_always and std::suspend_never . . . . . . . . . . . . . . . . . 257 5.4.4 initial_suspend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 5.4.5 final_suspend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 5.4.6 Awaiter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 5.5 The Workflows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 5.5.1 The Promise Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 5.5.2 The Awaiter Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 5.6 co_return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 5.6.1 A Future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 5.7 co_yield . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 5.7.1 An Infinite Data Stream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 5.8 co_await . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 5.8.1 Starting a Job on Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 5.8.2 Thread Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 5.9 std::generator (C++23) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Page 8
CONTENTS 6. Case Studies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 6.1 Calculating the Sum of a Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 6.1.1 Single-Threaded addition of a Vector . . . . . . . . . . . . . . . . . . . . . . 280 6.1.2 Multi-threaded Summation with a Shared Variable . . . . . . . . . . . . . . 286 6.1.3 Thread-Local Summation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 6.1.4 Summation of a Vector: The Conclusion . . . . . . . . . . . . . . . . . . . . 303 6.2 The Dining Philosophers Problem by Andre Adrian . . . . . . . . . . . . . . . . . . . 305 6.2.1 Multiple Resource Use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 6.2.2 Multiple Resource Use with Logging . . . . . . . . . . . . . . . . . . . . . . 308 6.2.3 Erroneous Busy Waiting without Resource Hierarchy . . . . . . . . . . . . . 309 6.2.4 Erroneous Busy Waiting with Resource Hierarchy . . . . . . . . . . . . . . . 310 6.2.5 Still Erroneous Busy Waiting with Resource Hierarchy . . . . . . . . . . . . 313 6.2.6 Correct Busy Waiting with Resource Hierarchy . . . . . . . . . . . . . . . . 315 6.2.7 Good low CPU load Busy Waiting with Resource Hierarchy . . . . . . . . . 317 6.2.8 std::mutex with Resource Hierarchy . . . . . . . . . . . . . . . . . . . . . . 318 6.2.9 std::lock_guard with Resource Hierarchy . . . . . . . . . . . . . . . . . . . 319 6.2.10 std::lock_guard and Synchronized Output with Resource Hierarchy . . . . 320 6.2.11 std::lock_guard and Synchronized Output with Resource Hierarchy and a count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 6.2.12 A std::unique_lock using deferred locking . . . . . . . . . . . . . . . . . . 323 6.2.13 A std::scoped_lock with Resource Hierarchy . . . . . . . . . . . . . . . . . 325 6.2.14 The Original Dining Philosophers Problem using Semaphores . . . . . . . . 326 6.2.15 A C++20 Compatible Semaphore . . . . . . . . . . . . . . . . . . . . . . . . 328 6.3 Thread-Safe Initialization of a Singleton . . . . . . . . . . . . . . . . . . . . . . . . . 330 6.3.1 Double-Checked Locking Pattern . . . . . . . . . . . . . . . . . . . . . . . . 330 6.3.2 Performance Measurement . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 6.3.3 Thread-Safe Meyers Singleton . . . . . . . . . . . . . . . . . . . . . . . . . 334 6.3.4 std::lock_guard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 6.3.5 std::call_once with std::once_flag . . . . . . . . . . . . . . . . . . . . . . 338 6.3.6 Atomics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 6.3.7 Performance Numbers of the various Thread-Safe Singleton Implementations 343 6.4 Ongoing Optimization with CppMem . . . . . . . . . . . . . . . . . . . . . . . . . . 345 6.4.1 CppMem: Non-Atomic Variables . . . . . . . . . . . . . . . . . . . . . . . . 347 6.4.2 CppMem: Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 6.4.3 CppMem: Atomics with Sequential Consistency . . . . . . . . . . . . . . . . 353 6.4.4 CppMem: Atomics with Acquire-Release Semantics . . . . . . . . . . . . . . 360 6.4.5 CppMem: Atomics with Non-atomics . . . . . . . . . . . . . . . . . . . . . 364 6.4.6 CppMem: Atomics with Relaxed Semantic . . . . . . . . . . . . . . . . . . . 366 6.4.7 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 6.5 Fast Synchronization of Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 6.5.1 Condition Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 6.5.2 std::atomic_flag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 6.5.3 std::atomic<bool> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
Page 9
CONTENTS 6.5.4 Semaphores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 6.5.5 All Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 6.6 Variations of Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 6.6.1 A Lazy Future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383 6.6.2 Execution on Another Thread . . . . . . . . . . . . . . . . . . . . . . . . . . 387 6.7 Modification and Generalization of a Generator . . . . . . . . . . . . . . . . . . . . . 391 6.7.1 Modifications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394 6.7.2 Generalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 6.8 Various Job Workflows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 6.8.1 The Transparent Awaiter Workflow . . . . . . . . . . . . . . . . . . . . . . 401 6.8.2 Automatically Resuming the Awaiter . . . . . . . . . . . . . . . . . . . . . . 403 6.8.3 Automatically Resuming the Awaiter on a Separate Thread . . . . . . . . . . 407 6.9 Thread-Safe Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 7. The Future of C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420 7.1 Executors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 7.1.1 A long Way . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 7.1.2 What is an Executor? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 7.1.3 First Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 7.1.4 Goals of an Executor Concept . . . . . . . . . . . . . . . . . . . . . . . . . . 427 7.1.5 Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 7.1.6 Execution Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 7.1.7 A Prototype Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 430 7.2 Extended Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 7.2.1 Concurrency TS v1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 7.2.2 Unified Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 7.3 Transactional Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 7.3.1 ACI(D) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 7.3.2 Synchronized and Atomic Blocks . . . . . . . . . . . . . . . . . . . . . . . . 444 7.3.3 transaction_safe versus transaction_unsafe Code . . . . . . . . . . . . . . 448 7.4 Task Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 7.4.1 Fork and Join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 7.4.2 define_task_block versus define_task_block_restore_thread . . . . . . . . 450 7.4.3 The Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451 7.4.4 The Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 7.5 Data-Parallel Vector Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 7.5.1 Data-Parallel Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 7.5.2 The Interface of the Data-Parallel Vectors . . . . . . . . . . . . . . . . . . . 454 Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 8. Patterns and Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460
Page 10
CONTENTS 8.1 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460 8.2 Invaluable Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 8.3 Pattern versus Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 8.4 Anti-Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 9. Synchronization Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464 9.1 Dealing with Sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 9.1.1 Copied Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 9.1.2 Thread-Specific Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 9.1.3 Future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 9.2 Dealing with Mutation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 9.2.1 Scoped Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474 9.2.2 Strategized Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 9.2.3 Thread-Safe Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487 9.2.4 Guarded Suspension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494 10. Concurrent Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 10.1 Active Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 10.1.1 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 10.1.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 10.1.3 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 10.1.4 Dynamic Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 10.1.5 Advantages and Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . 506 10.1.6 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506 10.2 Monitor Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 10.2.1 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 10.2.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 10.2.3 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 10.2.4 Dynamic Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513 10.2.5 Advantages and Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . 514 10.2.6 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 10.3 Half-Sync/Half-Async . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519 10.3.1 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519 10.3.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519 10.3.3 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 10.3.4 Dynamic Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521 10.3.5 Advantages and Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . 521 10.3.6 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 10.4 Reactor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 10.4.1 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 10.4.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 10.4.3 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 10.4.4 Dynamic Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
Page 11
CONTENTS 10.4.5 Advantages and Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . 525 10.4.6 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525 10.5 Proactor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530 10.5.1 Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 10.5.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 10.5.3 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 10.5.4 Advantages and Disadvantages . . . . . . . . . . . . . . . . . . . . . . . . . 533 10.5.5 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533 10.6 Further Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537 11. Best Practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 11.1 General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 11.1.1 Code Reviews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539 11.1.2 Minimize Sharing of Mutable Data . . . . . . . . . . . . . . . . . . . . . . . 541 11.1.3 Minimize Waiting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544 11.1.4 Prefer Immutable Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 11.1.5 Use pure functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547 11.1.6 Look for the Right Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . 548 11.1.7 Use Static Code Analysis Tools . . . . . . . . . . . . . . . . . . . . . . . . . 549 11.1.8 Use Dynamic Enforcement Tools . . . . . . . . . . . . . . . . . . . . . . . . 549 11.2 Multithreading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550 11.2.1 Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550 11.2.2 Data Sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555 11.2.3 Condition Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563 11.2.4 Promises and Futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566 11.3 Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 11.3.1 Don’t use volatile for synchronization . . . . . . . . . . . . . . . . . . . . . 567 11.3.2 Don’t program Lock Free . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567 11.3.3 If you program Lock-Free, use well-established patterns . . . . . . . . . . . 567 11.3.4 Don’t build your abstraction, use guarantees of the language . . . . . . . . . 568 11.3.5 Don’t reinvent the wheel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570 12. General Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 12.1 Concurrent Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571 12.2 Locking Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572 12.3 Granularity of the Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574 12.4 Typical Usage Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576 12.4.1 Linux (GCC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582 12.4.2 Windows (cl.exe) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 12.5 Avoidance of Loopholes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
Page 12
CONTENTS 12.6 Contention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586 12.6.1 Single-Threaded Summation without Synchronization . . . . . . . . . . . . 586 12.6.2 Single-Threaded Summation with Synchronization (lock) . . . . . . . . . . . 588 12.6.3 Single-Threaded Summation with Synchronization (atomic) . . . . . . . . . 589 12.6.4 The Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 12.7 Scalability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590 12.8 Invariants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592 12.9 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 13. Lock-Based Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596 13.1 Concurrent Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596 13.1.1 A Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597 13.2 Concurrent Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 13.2.1 A Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 13.2.2 Coarse-Grained Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604 13.2.3 Fine-Grained Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606 14. Lock-Free Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619 14.1 General Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620 14.1.1 The Next Evolutionary Step . . . . . . . . . . . . . . . . . . . . . . . . . . . 620 14.1.2 Sequential Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 620 14.2 Concurrent Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621 14.2.1 A Simplified Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 622 14.2.2 A Complete Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . 624 14.3 Concurrent Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647 Further Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .648 15. Challenges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649 15.1 ABA Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649 15.2 Blocking Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653 15.3 Breaking of Program Invariants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 15.4 Data Races . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656 15.5 Deadlocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 658 15.6 False Sharing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659 15.7 Lifetime Issues of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 664 15.8 Moving Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665 15.9 Race Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 666 16. The Time Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668 16.1 The Interplay of Time Point, Time Duration, and Clock . . . . . . . . . . . . . . . . . 669 16.2 Time Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 670
Page 13
CONTENTS 16.2.1 From Time Point to Calendar Time . . . . . . . . . . . . . . . . . . . . . . . 670 16.2.2 Cross the valid Time Range . . . . . . . . . . . . . . . . . . . . . . . . . . . 672 16.3 Time Duration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674 16.3.1 Calculations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676 16.4 Clocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679 16.4.1 Accuracy and Steadiness . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679 16.4.2 Epoch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682 16.5 Sleep and Wait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685 17. CppMem - An Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 17.1 The simplified Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 17.1.1 1. Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692 17.1.2 2. Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692 17.1.3 3. Display Relations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 17.1.4 4. Display Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 17.1.5 5. Model Predicates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 17.1.6 The Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 18. Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698 18.1 adress_free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698 18.2 ACID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698 18.3 CAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698 18.4 Callable Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698 18.5 Complexity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699 18.6 Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699 18.7 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699 18.8 Critical Section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699 18.9 Deadlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 18.10 Eager Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 18.11 Executor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 18.12 Function Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 18.13 Lambda Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701 18.14 Lazy evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701 18.15 Lock-free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701 18.16 Lock-based . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702 18.17 Lost Wakeup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702 18.18 Math Laws . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702 18.19 Memory Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702 18.20 Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 18.21 Modification Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 18.22 Monad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703 18.23 Non-blocking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704 18.24 obstruction-free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
Page 14
CONTENTS 18.25 Parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704 18.26 Predicate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705 18.27 Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705 18.28 RAII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705 18.29 Release Sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705 18.30 Sequential Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705 18.31 Sequence Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706 18.32 Spurious Wakeup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706 18.33 Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706 18.34 Total order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706 18.35 TriviallyCopyable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 18.36 Undefined Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 18.37 volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 18.38 wait-free . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
Page 15
Reader Testimonials Bart Vandewoestyne Senior Development Engineer Software at Esterline ”’Concurrency with Modern C++’ is your practical guide to getting familiar with concurrent programming in Modern C++. Starting with the C++ Memory Model and using many ready-to-run code examples, the book covers a good deal of what you need to improve your C++ multithreading skills. Next to the enlightening case studies that will bring you up to speed, the overview of upcoming concurrency features might even wet your appetite for more!” Ian Reeve Senior Storage Software Engineer for Dell Inc. ”Rainer Grimm’s Concurrency with Modern C++ is a well written book covering the theory and practice for working with concurrency per the existing C++ standards, as well as addressing the potential changes for the upcoming C++ 20 standard. He provides a conversational discussion of the applications and best practices for concurrency along with example code to reinforce the details of each topic. An informative and worthwhile read!” Robert Badea
Page 16
Reader Testimonials ii Technical Team Leader ”Concurrency with Modern C++ is the easiest way to become an expert in the multithreading environment. This book contains both simple and advanced topics, and it has everything a developer needs, in order to become an expert in this field: Lots of content, a big number of running code examples, along with great explanation, and a whole chapter for pitfalls. I enjoyed reading it, and I highly recommend it for everyone working with C++.”
Page 17
Introduction Concurrency with Modern C++ is a journey through the present and upcoming concurrency features in C++. • C++11 andC++14 have the basic building blocks for creating concurrent and parallel programs. • With C++17 we have the parallel algorithms from the Standard Template Library (STL). That means that most STL-based algorithms can be executed sequentially, in parallel, or vectorized. • The concurrency story in C++ goes on. With C++20, we got coroutines, atomic smart pointers, semaphores, latches, and barriers. • C++23 supports the first concrete coroutine: std::generator. • With future C++ standards, we can hope for executors, extended futures, transactional memory, and more. This book explains the details of concurrency inmodern C++ and even gives you, many code examples. Consequently, you can combine theory with practice to get the most out of it. Because this book is about concurrency, I’d like to present many pitfalls and show you how to overcome them. Conventions Only a few conventions. Special Fonts Italic: I use Italic to emphasize an expression. Bold: I use Bold to emphasize even more. Monospace: I use Monospace for code, instructions, keywords, and names of types, variables, functions, and classes. Special Symbols ⇒ stands for a conclusion in the mathematical sense. For example, a⇒ b means if a then b.
Page 18
Introduction iv Special Boxes Boxes contain tips, warnings, and distilled information. Tip Headline This box provides tips and additional information about the presented material. Warning Headline Warning boxes should help you to avoid pitfalls. Distilled Information This box summarizes at the end of each main section the important things to remember. Source Code All source code examples are complete. That means, assuming you have a conforming compiler, you can compile and run them. The name of the source file is in the title of the listing. I use the using namespace std directive in the source files only if necessary. Run the Programs Compiling and running the examples is quite easy for the C++20 examples in this book. Every modern C++ compiler should support them. For the GCC¹ and the clang² compiler, the C++ standard must be specified as well as the threading library. For example the g++ compiler from GCC creates an executable program called thread with the following command-line: g++ -std=c++20 -pthread thread.cpp -o thread. • -std=c++20: use the language standard C++20 • -pthread: add support for multithreading with the pthread library • thread.cpp: source file • -o thread: executable program ¹https://gcc.gnu.org/ ²https://clang.llvm.org/
Page 19
Introduction v The same command line holds for the clang++ compiler. The current Microsoft Visual Studio C++ compiler supports C++20 as well. If you have no modern C++ compiler at your disposal, there are many online compilers available. Arne Mertz’s blog post C++ Online Compiler³ gives an excellent overview. With the examples in the Future of C++, the story becomes pretty complicated. I installed the HPX (High Performance ParalleX)⁴ framework, which is a general-purpose C++ runtime system for parallel and distributed applications of any scale. HPX has already implemented the Parallel STL of C++17 and many of the concurrency features of C++20 and the upcoming C++ standard. How should you read the book? If you are not very familiar with concurrency in C++, start at the very beginning with A Quick Overview to get the big picture. Once you get the big picture, you can proceed with the chapter The Details. Skip the memory model in your first iteration of the book unless you are entirely sure that is what you are looking for. The chapter Case Studies should help you apply the theory. This is quite challenging as it requires a basic understanding of the memory model. The chapter about The Future of C++ is optional. I am very curious about the future. I hope you are too! The final part, Further Information provides you with additional guidance towards a better under- standing of my book and, finally, getting the most out of it. Personal Notes Acknowledgment I started a request in my English blog to write this book in English: www.ModernesCpp.com⁵ I receivedmuch higher response than I expected. About 50 people wanted to proofreadmy book. Special thanks to all of you, including my daughter Juliette, who improved my layout, and my son Marius as the first proofreader. Here are the names in alphabetic order: Nikos Athanasiou, Robert Badea, Florin Ioan Chertes, Joe Das, Jonas Devlieghere, Randy Hormann, Laszlo Kovacs, Lasse Natvig, Erik Newton, Ian Reeve, Bart Vandewoestyne, Vadim Vinnik, Dafydd Walters, Andrzej Warzynski, and Enrico Zschemisch. ³https://arne-mertz.de/2017/05/online-compilers/ ⁴http://stellar.cct.lsu.edu/projects/hpx/ ⁵http://www.modernescpp.com/index.php/looking-for-proofreaders-for-my-new-book-concurrency-with-modern-c
Page 20
Introduction vi About Me I’ve worked as a software architect, team lead, and instructor since 1999. In 2002, I created company- intern meetings for further education. I have given training courses since 2002. My first tutorials were about proprietary management software, but I began teaching Python and C++ soon after. In my spare time, I like to write articles about C++, Python, and Haskell. I also like to speak at conferences. I publish weekly on my English blog Modernes Cpp⁶ and the German blog⁷, hosted by Heise Developer. Since 2016, I have been an independent instructor and mentor giving seminars about modern C++ and Python. I have published several books in various languages about modern C++ and, in particular, about concurrency. Due to my profession, I always search for the best way to teach modern C++. Rainer Grimm ⁶https://www.modernescpp.com/ ⁷https://www.grimm-jaud.de/index.php/blog
The above is a preview of the first 20 pages. Register to read the complete e-book.

Recommended for You

Loading recommended books...
Failed to load, please try again later

Tip the Site

Scan the WeChat Pay or Alipay code to tip. No login required.

WeChat Pay
Alipay
← Back to List