Concurrency & Multithreading Flashcards
7 cards from real CPP practice questions. Tap to flip, then mark Knew It or Still Learning — missed cards come back until you master them.
Read the first 7 Concurrency & Multithreading flashcards as text
What is the purpose of `std::barrier` introduced in C++20?
Answer: To synchronize a fixed number of threads at a checkpoint before any can proceed past it
`std::barrier` synchronizes a set of threads at a reusable synchronization point; all participating threads must arrive before any can continue, and it resets for the next phase.
What distinguishes `std::latch` from `std::barrier` in C++20?
Answer: `std::latch` is a single-use countdown that threads can wait on; `std::barrier` is reusable across multiple phases
`std::latch` is a one-shot downward counter — once it reaches zero it stays open; `std::barrier` resets after each synchronization phase, making it suitable for iterative parallel work.
What is a semaphore, and which C++20 class provides one?
Answer: A counting synchronization primitive; provided by `std::counting_semaphore`
A semaphore is a counting synchronization primitive; C++20 provides `std::counting_semaphore` (and `std::binary_semaphore` as a specialization with max count 1).
What does `std::memory_order_relaxed` guarantee?
Answer: Only atomicity of the operation itself with no synchronization or ordering constraints
`memory_order_relaxed` provides only atomicity — the operation is indivisible — but places no ordering constraints relative to other memory operations in the same or other threads.
In a producer-consumer pattern using `std::atomic`, why might `memory_order_release` on the store and `memory_order_acquire` on the load be preferred over `memory_order_seq_cst`?
Answer: Release-acquire is sufficient to establish happens-before and avoids the global ordering overhead of seq_cst
A release store paired with an acquire load establishes the necessary happens-before relationship at lower cost than `seq_cst`, which requires a global total order across all threads.
What problem does `std::scoped_lock` (C++17) solve compared to calling `std::mutex::lock()` on multiple mutexes in sequence?
Answer: It prevents deadlock by acquiring all mutexes atomically using a deadlock-avoidance algorithm
`std::scoped_lock` acquires multiple mutexes using a deadlock-avoidance algorithm (equivalent to `std::lock`), preventing the classic lock-ordering deadlock when two threads acquire the same two mutexes in opposite order.
What is the purpose of the `volatile` keyword in C++ with respect to multithreading?
Answer: It prevents the compiler from caching the variable in a register, primarily for hardware-mapped I/O; it does NOT provide thread synchronization
`volatile` tells the compiler not to optimize away reads/writes (for memory-mapped I/O), but it provides no atomicity, memory ordering, or thread-safety guarantees — use `std::atomic` for shared mutable state between threads.