- Артикул:00-01120634
- ISBN: 978-1-83588-424-9
- Обложка: Мягкая обложка
- Издательство: Packt (все книги издательства)
- Город: UK
- Страниц: 423
- Год: 2024
- Вес: 1070 г
Издание на английском языке
This book explores asynchronous programming in C++, from thread management and synchronization to advanced optimization and debugging techniques. It explains the basic concepts, asynchronous models, and popular libraries such as Boost.Asio and Cobalt. It places particular emphasis on practical aspects: creating multithreaded applications, error handling, testing, and performance improvement. After reading, you'll be able to effectively build asynchronous systems, solve real-world problems, and optimize complex scenarios for modern multi-core processors.
Content
Preface
Part 1: Foundations of Parallel Programming and Process Management
1. Parallel Programming Paradigms
Technical requirements
Getting to know classifications, techniques, and models
Systems classification and techniques
Parallel programming models
Understanding various parallel programming paradigms
Synchronous programming
Concurrency programming
Asynchronous programming
Parallel programming
Multithreading programming
Event-driven programming
Reactive programming
Dataflow programming
Exploring the metrics to assess parallelism
Degree of parallelism
Amdahl's law
Gustafson's law
Summary
Further reading
2. Processes, Threads, and Services
Processes in Linux
Process life cycle - creation, execution, and termination
Exploring IPC
Services and daemons in Linux
Threads
Thread life cycle
Thread scheduling
Synchronization primitives
Choosing the right synchronization primitive
Common problems when using multiple threads
Strategies for effective thread management
Summary
Further reading
3. How to Create and Manage Threads in C++
Technical requirements
The thread library - an introduction
What are threads? Let's do a recap
The C++ thread library
Thread operations
Thread creation
Synchronized stream writing
Sleeping the current thread
Identifying a thread
Passing arguments
Returning values
Moving threads
Waiting for a thread to finish
Joining threads - the jthread class
Yielding thread execution
Threads cancellation
Catching exceptions
Thread-local storage
Implementing a timer
Summary
Further reading
4. Thread Synchronization with Locks
Technical requirements
Understanding race conditions
Why do we need mutual exclusion?
C++ Standard Library mutual exclusion implementation
Problems when using locks
Generic lock management
std::lock_guard
std::unique_lock
std::scoped_lock
std::shared_lock
Condition variables
Implementing a multithreaded safe queue
Semaphores
Binary semaphores
Counting semaphores
Barriers and latches
std::latch
std::barrier
Performing a task only once
Summary
Further reading
5. Atomic Operations
Technical requirements
Introduction to atomic operations
Atomic operations versus non-atomic operations - an example
When to use (and when not to use) atomic operations
Non-blocking data structures
The C++ memory model
Memory access order
Enforcing ordering
Sequential consistency
Acquire-release ordering
Relaxed memory ordering
C++ Standard Library atomic types and operations
C++ Standard Library atomic types
C++ Standard Library atomic operations
Example - simple spin-lock implemented using the C++ atomic flag
An example of thread progress reporting
Example - simple statistics
Example - lazy one-time initialization
SPSC lock-free queue
Why do we use a power of 2 buffer size?
Buffer access synchronization
Pushing elements into the queue
Popping elements from the queue
Summary
Further reading
Part 3: Asynchronous Programming with Promises, Futures, and Coroutines
6. Promises and Futures
Technical requirements
Exploring promises and futures
Promises
Futures
Shared futures
Packaged tasks
The benefits and drawbacks of promises and futures
Benefits
Drawbacks
Examples of real-life scenarios and solutions
Canceling asynchronous operations
Returning combined results
Chaining asynchronous operations
Thread-safe SPSC task queue
Summary
Further reading
7. The Async Function
Technical requirements
What is std::async?
Launching an asynchronous task
Passing values
Returning values
Launch policies
Handling exceptions
Exceptions when calling std::async
Async futures and performance
Limiting the number of threads
When not to use std::async
Practical examples
Parallel computation and aggregation
Asynchronous searches
Asynchronous matrix multiplication
Chain asynchronous operations
Asynchronous pipeline
Summary
Further reading
8. Asynchronous Programming Using Coroutines
Technical requirements
Coroutines
C++ coroutines
New keywords
Coroutines restrictions
Implementing basic coroutines
The simplest coroutine
A yielding coroutine
A waiting coroutine
Coroutine generators
Fibonacci sequence generator
Simple coroutine string parser
The parsing algorithm
The parsing coroutine
Coroutines and exceptions
Summary
Further reading
Part 4: Advanced Asynchronous Programming with Boost Libraries
9. Asynchronous Programming Using Boost. Asio
Technical requirements
What is Boost. Asio?
I/O objects
I/O execution context objects
The event processing loop
Interacting with the OS
Synchronous operations
Asynchronous operations
The Reactor and Proactor design patterns
Threading with Boost. Asio
Single-threaded approach
Threaded long-running tasks
Multiple I/O execution context objects, one per thread
Multiple threads with a single I/O execution context object
Parallelizing work done by one I/O execution context
Managing objects' lifetime
Implementing an echo server - an example
Transferring data using buffers
Scatter-gather operations
Stream buffers
Signal handling
Canceling operations
Serializing workload with strands
Coroutines
Summary
Further reading
10. Coroutines with Boost. Cobalt
Technical requirements
Introducing the Boost. Cobalt library
Eager and lazy coroutines
Boost. Cobalt coroutine types
Boost. Cobalt generators
Looking at a basic example
Boost. Cobalt simple generators
A Fibonacci sequence generator
Boost. Cobalt tasks and promises
Boost. Cobalt channels
Boost. Cobalt synchronization functions
Summary
Further reading
Part 5: Debugging, Testing, and Performance Optimization in Asynchronous Programming
11. Logging and Debugging Asynchronous Software
Technical requirements
How to use logging to spot bugs
How to select a third-party library
Some relevant logging libraries
Logging a deadlock - an example
How to debug asynchronous software
Some useful GDB commands
Debugging multithreaded programs
Debugging race conditions
Reverse debugging
Debugging coroutines
Summary
Further reading
12. Sanitizing and Testing Asynchronous Software
Technical requirements
Sanitizing code to analyze the software and find potential issues
Compiler options
Address Sanitizer
Leak Sanitizer
Thread Sanitizer
Undefined Behavior Sanitizer
Memory Sanitizer
Other sanitizers
Testing asynchronous code
Testing a simple asynchronous function
Limiting test durations by using timeouts
Testing callbacks
Testing event-driven software
Mocking external resources
Testing exceptions and failures
Testing multiple threads
Testing coroutines
Stress testing
Parallelizing tests
Summary
Further reading
13. Improving Asynchronous Software Performance
Technical requirements
Performance measurement tools
In-code profiling
Code micro-benchmarks
The Linux perf tool
False sharing
CPU memory cache
Cache coherency
SPSC lock-free queue
Summary
Further reading
Index
Other Books You May Enjoy

