C++ Concurrency in Action, Second Edition
Anthony Williams
  • MEAP began March 2017
  • Publication in September 2018 (estimated)
  • ISBN 9781617294693
  • 575 pages (estimated)
  • printed in black & white

This text is a must have for everybody interested in using the facilities provided by the C++11/14/17 standards.

Maurizio Tomasi


An eBook copy of the previous edition, C++ Concurrency in Action (First Edition), is included at no additional cost. It will be automatically added to your Manning Bookshelf within 24 hours of purchase.

This bestseller has been updated and revised to cover all the latest changes to C++ 14 and 17! C++ Concurrency in Action, Second Edition teaches you everything you need to write robust and elegant multithreaded applications in C++17. You'll discover the basics of starting new threads, how to synchronize operations between threads, designing multithreaded algorithms and data structures, and more. Along the way, you'll learn how to navigate the trickier bits of programming for concurrency while avoiding the common pitfalls.

Table of Contents detailed table of contents

1. Hello, world of concurrency in C++!

1.1. What is concurrency?

1.1.1. Concurrency in computer systems

1.1.2. Approaches to concurrency

1.1.3. Concurrency vs Parallelism

1.2. Why use concurrency?

1.2.1. Using concurrency for separation of concerns

1.2.2. Using concurrency for performance: task parallelism and data parallelism

1.2.3. When not to use concurrency

1.3. Concurrency and multithreading in C++

1.3.1. History of multithreading in C++

1.3.2. Concurrency support in the C++11 standard

1.3.3. More support for Concurrency and Parallelism in C++14 and C++17

1.3.4. Efficiency in the C++ Thread Library

1.3.5. Platform-specific facilities

1.4. Getting started

1.4.1. Hello, Concurrent World

1.5. Summary

2. Managing threads

2.1. Basic thread management

2.1.1. Launching a thread

2.1.2. Waiting for a thread to complete

2.1.3. Waiting in exceptional circumstances

2.1.4. Running threads in the background

2.2. Passing arguments to a thread function

2.3. Transferring ownership of a thread

2.4. Choosing the number of threads at runtime

2.5. Identifying threads

2.6. Summary

3. Sharing data between threads

3.1. Problems with sharing data between threads

3.1.1. Race conditions

3.1.2. Avoiding problematic race conditions

3.2. Protecting shared data with mutexes

3.2.1. Using mutexes in C++

3.2.2. Structuring code for protecting shared data

3.2.3. Spotting race conditions inherent in interfaces

3.2.4. Deadlock: the problem and a solution

3.2.5. Further guidelines for avoiding deadlock

3.2.6. Flexible locking with std::unique_lock

3.2.7. Transferring mutex ownership between scopes

3.2.8. Locking at an appropriate granularity

3.3. Alternative facilities for protecting shared data

3.3.1. Protecting shared data during initialization

3.3.2. Protecting rarely updated data structures

3.3.3. Recursive locking

3.4. Summary

4. Synchronizing concurrent operations

4.1. Waiting for an event or other condition

4.1.1. Waiting for a condition with condition variables

4.1.2. Building a thread-safe queue with condition variables

4.2. Waiting for one-off events with futures

4.2.1. Returning values from background tasks

4.2.2. Associating a task with a future

4.2.3. Making (std::)promises

4.2.4. Saving an exception for the future

4.2.5. Waiting from multiple threads

4.3. Waiting with a time limit

4.3.1. Clocks

4.3.2. Durations

4.3.3. Time points

4.3.4. Functions that accept timeouts

4.4. Using synchronization of operations to simplify code

4.4.1. Functional programming with futures

4.4.2. Synchronizing operations with message passing

4.4.3. Continuation-style concurrency with the Concurrency TS

4.4.4. Chaining continuations

4.4.5. Waiting for more than one future

4.4.6. Waiting for the first future in a set with when_any

4.4.7. Latches and Barriers in the Concurrency TS

4.4.8. A basic latch type: std::experimental::latch

4.4.9. std::experimental::barrier: a basic barrier

4.4.10. std::experimental::flex_barrier —std::experimental::barrier’s flexible friend

4.5. Summary

5. The C++ memory model and operations on atomic types

5.1. Memory model basics

5.1.1. Objects and memory locations

5.1.2. Objects, memory locations, and concurrency

5.1.3. Modification orders

5.2. Atomic operations and types in C++

5.2.1. The standard atomic types

5.2.2. Operations on std::atomic_flag

5.2.3. Operations on std::atomic<bool>

5.2.4. Operations on std::atomic<T*> pointer arithmetic

5.2.5. Operations on standard atomic integral types

5.2.6. The std::atomic<> primary class template

5.2.7. Free functions for atomic operations

5.3. Synchronizing operations and enforcing ordering

5.3.1. The synchronizes-with relationship

5.3.2. The happens-before relationship

5.3.3. Memory ordering for atomic operations

5.3.4. Release sequences and synchronizes-with

5.3.5. Fences

5.3.6. Ordering nonatomic operations with atomics

5.3.7. Ordering non-atomic operations

5.4. Summary

6. Designing lock-based concurrent data structures

6.1. What does it mean to design for concurrency?

6.1.1. Guidelines for designing data structures for concurrency

6.2. Lock-based concurrent data structures

6.2.1. A thread-safe stack using locks

6.2.2. A thread-safe queue using locks and condition variables

6.2.3. A thread-safe queue using fine-grained locks and condition variables

6.3. Designing more complex lock-based data structures

6.3.1. Writing a thread-safe lookup table using locks

6.3.2. Writing a thread-safe list using locks

6.4. Summary

7. Designing lock-free concurrent data structures

7.1. Definitions and consequences

7.1.1. Types of nonblocking data structures

7.1.2. Lock-free data structures

7.1.3. Wait-free data structures

7.1.4. The pros and cons of lock-free data structures

7.2. Examples of lock-free data structures

7.2.1. Writing a thread-safe stack without locks

7.2.2. Stopping those pesky leaks: managing memory in lock-free data structures

7.2.3. Detecting nodes that can’t be reclaimed using hazard pointers

7.2.4. Detecting nodes in use with reference counting

7.2.5. Applying the memory model to the lock-free stack

7.2.6. Writing a thread-safe queue without locks

7.3. Guidelines for writing lock-free data structures

7.3.1. Guideline: use std::memory_order_seq_cst for prototyping

7.3.2. Guideline: use a lock-free memory reclamation scheme

7.3.3. Guideline: watch out for the ABA problem

7.3.4. Guideline: identify busy-wait loops and help the other thread

7.4. Summary

8. Designing concurrent code

8.1. Techniques for dividing work between threads

8.1.1. Dividing data between threads before processing begins

8.1.2. Dividing data recursively

8.1.3. Dividing work by task type

8.2. Factors affecting the performance of concurrent code

8.2.1. How many processors?

8.2.2. Data contention and cache ping-pong

8.2.3. False sharing

8.2.4. How close is your data?

8.2.5. Oversubscription and excessive task switching

8.3. Designing data structures for multithreaded performance

8.3.1. Dividing array elements for complex operations

8.3.2. Data access patterns in other data structures

8.4. Additional considerations when designing for concurrency

8.4.1. Exception safety in parallel algorithms

8.4.2. Scalability and Amdahl’s law

8.4.3. Hiding latency with multiple threads

8.4.4. Improving responsiveness with concurrency

8.5. Designing concurrent code in practice

8.5.1. A parallel implementation of std::for_each

8.5.2. A parallel implementation of std::find

8.5.3. A parallel implementation of std::partial_sum

8.6. Summary

9. Advanced thread management

9.1. Thread pools

9.1.1. The simplest possible thread pool

9.1.2. Waiting for tasks submitted to a thread pool

9.1.3. Tasks that wait for other tasks

9.1.4. Avoiding contention on the work queue

9.1.5. Work stealing

9.2. Interrupting threads

9.2.1. Launching and interrupting another thread

9.2.2. Detecting that a thread has been interrupted

9.2.3. Interrupting a condition variable wait

9.2.4. Interrupting a wait on std::condition_variable_any

9.2.5. Interrupting other blocking calls

9.2.6. Handling interruptions

9.2.7. Interrupting background tasks on application exit

9.3. Summary

10. Parallel Algorithms

10.1. Parallelizing the Standard Library Algorithms

10.2. Execution Policies

10.2.1. General effects of specifying an execution policy

10.2.2. std::execution::sequenced_policy

10.2.3. std::execution::parallel_policy

10.2.4. std::execution::parallel_unsequenced_policy

10.3. The Parallel Algorithms from the C++ Standard Library

10.3.1. Examples of using parallel algorithms

10.3.2. Counting visits

10.4. Summary

11. Testing and debugging multithreaded applications

11.1.1. Unwanted blocking

11.1.2. Race conditions

11.2.1. Reviewing code to locate potential bugs

11.2.3. Designing for testability

11.2.4. Multithreaded testing techniques

11.2.5. Structuring multithreaded test code

11.2.6. Testing the performance of multithreaded code

11.3. Summary

About the Technology

C++ may seem like the grandfather of modern programming languages, but this is one spritely old dude! C++ 11 delivered strong support for multithreaded applications, and the subsequent C++14 and 17 updates have built on this baseline. C++ has better options for concurrency than ever before, which means it's an incredibly powerful option for multicore and parallel applications.

What's inside

  • Managing threads
  • Synchronizing concurrent operations
  • Designing concurrent code
  • Advanced thread management
  • Parallel Algorithms
  • Debugging multithreaded applications

About the reader

Written for C++ programmers who are new to concurrency and others who may have written multithreaded code using other languages, APIs, or platforms.

About the author

Anthony Williams is a UK-based developer and consultant with many years' experience in C++. He has been an active member of the BSI C++ Standards Panel since 2001, and is the author or co-author of many of the C++ Standards Committee papers that led up to the inclusion of the thread library in the C++11 Standard. He was the maintainer of the Boost Thread library, and is the developer of the just::thread Pro extensions to the C++11 thread library from Just Software Solutions Ltd.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
C++ Concurrency in Action, Second Edition (combo) added to cart
continue shopping
go to cart

MEAP combo $69.99 pBook + eBook + liveBook
C++ Concurrency in Action, Second Edition (eBook) added to cart
continue shopping
go to cart

MEAP eBook $55.99 pdf + ePub + kindle + liveBook

FREE domestic shipping on three or more pBooks

A clear and concise book that gives a thorough overview of built-in parallel constructs in C++ and their applications.

Robert C. Green II

The most comprehensive book on writing concurrent code using the latest C++17 features.

Steven Parr