Cover....1
Table of Contents ....8
Preface....16
Part 1: Foundations of Parallel Programming and Process Management....22
Chapter 1: Parallel Programming Paradigms....24
Technical requirements....24
Getting to know classifications, techniques, and models....25
Systems classification and techniques....25
Parallel programming models....27
Understanding various parallel programming paradigms....30
Synchronous programming....31
Concurrency programming....31
Asynchronous programming....34
Parallel programming....34
Multithreading programming....35
Event-driven programming....35
Reactive programming....35
Dataflow programming....37
Exploring the metrics to assess parallelism....37
Degree of parallelism....37
Amdahl’s law....38
Gustafson’s law....39
Summary....40
Further reading....40
Chapter 2: Processes, Threads, and Services....42
Processes in Linux....43
Process life cycle – creation, execution, and termination....43
Exploring IPC....44
Services and daemons in Linux....47
Threads....49
Thread life cycle....50
Thread scheduling....51
Synchronization primitives....52
Choosing the right synchronization primitive....52
Common problems when using multiple threads....53
Strategies for effective thread management....54
Summary....56
Further reading....56
Part 2: Advanced Thread Management and Synchronization Techniques....58
Chapter 3: How to Create and Manage Threads in C++....60
Technical requirements....61
The thread library – an introduction....61
What are threads? Let’s do a recap....61
The C++ thread library....62
Thread operations....62
Thread creation....62
Synchronized stream writing....64
Sleeping the current thread....66
Identifying a thread....67
Passing arguments....68
Returning values....69
Moving threads....71
Waiting for a thread to finish....71
Joining threads – the jthread class....74
Yielding thread execution....76
Threads cancellation....78
Catching exceptions....82
Thread-local storage....84
Implementing a timer....85
Summary....88
Further reading....88
Chapter 4: Thread Synchronization with Locks....90
Technical requirements....90
Understanding race conditions....91
Why do we need mutual exclusion?....93
C++ Standard Library mutual exclusion implementation....95
Problems when using locks....101
Generic lock management....102
std::lock_guard....103
std::unique_lock....104
std::scoped_lock....105
std::shared_lock....105
Condition variables....106
Implementing a multithreaded safe queue....108
Semaphores....116
Binary semaphores....116
Counting semaphores....117
Barriers and latches....122
std::latch....122
std::barrier....123
Performing a task only once....127
Summary....129
Further reading....129
Chapter 5: Atomic Operations....130
Technical requirements....130
Introduction to atomic operations....131
Atomic operations versus non-atomic operations – an example....131
When to use (and when not to use) atomic operations....132
Non-blocking data structures....133
The C++ memory model....134
Memory access order....135
Enforcing ordering....138
Sequential consistency....139
Acquire-release ordering....142
Relaxed memory ordering....144
C++ Standard Library atomic types and operations....145
C++ Standard Library atomic types....145
C++ Standard Library atomic operations....146
Example – simple spin-lock implemented using the C++ atomic flag....147
An example of thread progress reporting....150
Example – simple statistics....151
Example – lazy one-time initialization....156
SPSC lock-free queue....159
Why do we use a power of 2 buffer size?....160
Buffer access synchronization....160
Pushing elements into the queue....161
Popping elements from the queue....162
Summary....164
Further reading....165
Part 3: Asynchronous Programming with Promises, Futures, and Coroutines....166
Chapter 6: Promises and Futures....168
Technical requirements....168
Exploring promises and futures....169
Promises....170
Futures....173
Shared futures....177
Packaged tasks....178
The benefits and drawbacks of promises and futures....181
Benefits....182
Drawbacks....182
Examples of real-life scenarios and solutions....182
Canceling asynchronous operations....183
Returning combined results....184
Chaining asynchronous operations....186
Thread-safe SPSC task queue....191
Summary....194
Further reading....195
Chapter 7: The Async Function....196
Technical requirements....196
What is std::async?....197
Launching an asynchronous task....197
Passing values....198
Returning values....200
Launch policies....201
Handling exceptions....204
Exceptions when calling std::async....206
Async futures and performance....207
Limiting the number of threads....210
When not to use std::async....212
Practical examples....212
Parallel computation and aggregation....212
Asynchronous searches....214
Asynchronous matrix multiplication....218
Chain asynchronous operations....221
Asynchronous pipeline....222
Summary....227
Further reading....227
Chapter 8: Asynchronous Programming Using Coroutines....228
Technical requirements....229
Coroutines....229
C++ coroutines....230
New keywords....231
Coroutines restrictions....232
Implementing basic coroutines....232
The simplest coroutine....232
A yielding coroutine....236
A waiting coroutine....241
Coroutine generators....245
Fibonacci sequence generator....245
Simple coroutine string parser....249
The parsing algorithm....249
The parsing coroutine....251
Coroutines and exceptions....254
Summary....255
Further reading....255
Part 4: Advanced Asynchronous Programming with Boost Libraries....256
Chapter 9: Asynchronous Programming Using Boost.Asio....258
Technical requirements....259
What is Boost.Asio?....259
I/O objects....260
I/O execution context objects....261
The event processing loop....266
Interacting with the OS....267
Synchronous operations....267
Asynchronous operations....268
The Reactor and Proactor design patterns....270
Threading with Boost.Asio....271
Single-threaded approach....272
Threaded long-running tasks....273
Multiple I/O execution context objects, one per thread....274
Multiple threads with a single I/O execution context object....275
Parallelizing work done by one I/O execution context....276
Managing objects’ lifetime....278
Implementing an echo server – an example....278
Transferring data using buffers....282
Scatter-gather operations....283
Stream buffers....284
Signal handling....286
Canceling operations....288
Serializing workload with strands....290
Coroutines....297
Summary....301
Further reading....301
Chapter 10: Coroutines with Boost.Cobalt....304
Technical requirements....304
Introducing the Boost.Cobalt library....305
Eager and lazy coroutines....306
Boost.Cobalt coroutine types....306
Boost.Cobalt generators....307
Looking at a basic example....307
Boost.Cobalt simple generators....308
A Fibonacci sequence generator....311
Boost.Cobalt tasks and promises....313
Boost.Cobalt channels....317
Boost.Cobalt synchronization functions....319
Summary....323
Further reading....323
Part 5: Debugging, Testing, and Performance Optimization in Asynchronous Programming....324
Chapter 11: Logging and Debugging Asynchronous Software....326
Technical requirements....326
How to use logging to spot bugs....327
How to select a third-party library....328
Some relevant logging libraries....328
Logging a deadlock – an example....330
How to debug asynchronous software....334
Some useful GDB commands....334
Debugging multithreaded programs....336
Debugging race conditions....339
Reverse debugging....341
Debugging coroutines....343
Summary....346
Further reading....346
Chapter 12: Sanitizing and Testing Asynchronous Software....348
Technical requirements....348
Sanitizing code to analyze the software and find potential issues....349
Compiler options....350
AddressSanitizer....352
LeakSanitizer....355
ThreadSanitizer....356
UndefinedBehaviorSanitizer....363
MemorySanitizer....363
Other sanitizers....364
Testing asynchronous code....365
Testing a simple asynchronous function....366
Limiting test durations by using timeouts....367
Testing callbacks....368
Testing event-driven software....369
Mocking external resources....370
Testing exceptions and failures....373
Testing multiple threads....374
Testing coroutines....376
Stress testing....380
Parallelizing tests....381
Summary....381
Further reading....381
Chapter 13: Improving Asynchronous Software Performance....384
Technical requirements....384
Performance measurement tools....385
In-code profiling....385
Code micro-benchmarks....388
The Linux perf tool....395
False sharing....400
CPU memory cache....403
Cache coherency....404
SPSC lock-free queue....405
Summary....409
Further reading....409
Index....410
Other Books You May Enjoy....421
Design and develop high-performance software solutions by using concurrent and asynchronous techniques provided by the most modern features in C++20 and C++23
As hardware advancements continue to accelerate, bringing greater memory capacity and more CPU cores, software must evolve to adapt to efficiently use all available resources and reduce idle CPU cycles. In this book, two seasoned software engineers with about five decades of combined experience will teach you how to implement concurrent and asynchronous solutions in C++. You’ll gain a comprehensive understanding of parallel programming paradigms—covering concurrent, asynchronous, parallel, multithreading, reactive, and event-driven programming, as well as dataflows—and see how threads, processes, and services are related. Moving into the heart of concurrency, the authors will guide you in creating and managing threads and exploring C++’s thread-safety mechanisms, including mutual exclusion, atomic operations, semaphores, condition variables, latches, and barriers. With this solid foundation, you’ll focus on pure asynchronous programming, discovering futures, promises, the async function, and coroutines. The book takes you step by step through using Boost.Asio and Boost.Cobalt to develop network and low-level I/O solutions, proven performance and optimization techniques, and testing and debugging asynchronous software. By the end of this C++ book, you’ll be able to implement high-performance software using modern asynchronous C++ techniques.
This book is for developers who have some experience using C++, regardless of their professional field. If you want to improve your C++ skills and learn how to develop high-performance software using the latest modern C++ features, this book is for you.
What you will learn