C++ Concurrency Quiz
40 in-depth questions covering C++ concurrency with std::thread, thread synchronization, mutex types, condition variables, and race condition avoidance — with 16 code examples to solidify understanding.
Question 1
What is the purpose of std::thread in C++?
Question 2
What is a race condition in concurrent programming?
int counter = 0;
void increment() {
for (int i = 0; i < 1000; ++i) {
counter++; // Race condition: not atomic
}
}
// Two threads calling increment() may interleave
// Result: counter < 2000Question 3
What is the purpose of std::mutex?
#include <mutex>
std::mutex mtx;
int counter = 0;
void increment() {
std::lock_guard<std::mutex> lock(mtx);
counter++; // Now thread-safe
}Question 4
What is the difference between std::lock_guard and std::unique_lock?
std::mutex mtx;
void func1() {
std::lock_guard<std::mutex> lock(mtx); // RAII, cannot unlock early
// Critical section
} // Automatic unlock
void func2() {
std::unique_lock<std::mutex> lock(mtx); // More flexible
// Can unlock early
lock.unlock();
// Do something else
lock.lock(); // Lock again
}Question 5
What is a deadlock in concurrent programming?
std::mutex mtx1, mtx2;
void thread1() {
std::lock_guard<std::mutex> lock1(mtx1);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> lock2(mtx2); // Deadlock!
}
void thread2() {
std::lock_guard<std::mutex> lock2(mtx2);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> lock1(mtx1); // Deadlock!
}Question 6
What is the purpose of condition variables?
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> queue;
void producer() {
std::unique_lock<std::mutex> lock(mtx);
queue.push(42);
cv.notify_one(); // Notify waiting thread
}
void consumer() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return !queue.empty(); }); // Wait for data
int data = queue.front();
}Question 7
What is the difference between join() and detach() in std::thread?
std::thread t(func);
t.join(); // Wait for thread to finish
// Thread resources cleaned up
std::thread t2(func);
t2.detach(); // Let thread run independently
// Thread continues, main thread doesn't wait
// Thread resources may not be cleaned up properlyQuestion 8
What is thread safety?
Question 9
What is the purpose of std::atomic?
#include <atomic>
std::atomic<int> counter = 0;
void increment() {
for (int i = 0; i < 1000; ++i) {
counter++; // Atomic operation, no race condition
}
}Question 10
What is lock contention?
Question 11
What is the difference between std::mutex and std::recursive_mutex?
std::mutex mtx;
void func() {
std::lock_guard<std::mutex> lock(mtx);
// Cannot call func() again - deadlock
}
std::recursive_mutex rmtx;
void recursive_func() {
std::lock_guard<std::recursive_mutex> lock(rmtx);
// Can call recursive_func() again - same thread
}Question 12
What is thread local storage?
thread_local int counter = 0;
void increment() {
counter++; // Each thread has its own counter
}
// Thread 1: counter = 1
// Thread 2: counter = 1 (separate variable)Question 13
What is the purpose of std::call_once?
#include <mutex>
std::once_flag flag;
int* data = nullptr;
void init() {
data = new int(42);
}
void thread_func() {
std::call_once(flag, init); // init called only once
// Use data safely
}Question 14
What is the difference between spurious wakeup and lost wakeup?
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void waiter() {
std::unique_lock<std::mutex> lock(mtx);
while (!ready) { // Prevent spurious wakeup
cv.wait(lock);
}
}
void notifier() {
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one(); // Must be done while NOT holding lock
}Question 15
What is lock-free programming?
#include <atomic>
std::atomic<int> counter = 0;
void increment() {
counter.fetch_add(1, std::memory_order_relaxed);
// No locks, but atomic operations
}Question 16
What is the difference between std::thread and std::jthread (C++20)?
std::thread t(func); // Must join or detach manually
t.join();
std::jthread jt(func); // Automatic join on destruction
// No manual join neededQuestion 17
What is memory ordering in atomic operations?
std::atomic<int> x = 0, y = 0;
void thread1() {
x.store(1, std::memory_order_relaxed);
y.store(1, std::memory_order_release);
}
void thread2() {
while (y.load(std::memory_order_acquire) != 1);
assert(x.load(std::memory_order_relaxed) == 1); // May fail without proper ordering
}Question 18
What is the difference between busy waiting and blocking synchronization?
// Busy waiting
bool ready = false;
void waiter() {
while (!ready) { /* do nothing */ } // Wastes CPU
}
// Blocking synchronization
std::mutex mtx;
std::condition_variable cv;
void waiter() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; }); // Sleeps until notified
}Question 19
What is thread pool pattern?
class ThreadPool {
std::vector<std::thread> workers;
std::queue<std::function<void()>> tasks;
std::mutex queue_mutex;
std::condition_variable cv;
public:
void enqueue(std::function<void()> task) {
std::unique_lock<std::mutex> lock(queue_mutex);
tasks.push(task);
cv.notify_one();
}
// Worker threads continuously dequeue and execute tasks
};Question 20
What is the difference between data race and race condition?
Question 21
What is the purpose of std::shared_mutex?
#include <shared_mutex>
std::shared_mutex smtx;
int data = 0;
void reader() {
std::shared_lock<std::shared_mutex> lock(smtx);
// Multiple readers can read simultaneously
int value = data;
}
void writer() {
std::unique_lock<std::shared_mutex> lock(smtx);
// Only one writer, no readers
data = 42;
}Question 22
What is the difference between thread creation and thread spawning?
Question 23
What is the purpose of std::promise and std::future?
#include <future>
std::promise<int> promise;
std::future<int> future = promise.get_future();
void producer() {
int result = compute_value();
promise.set_value(result);
}
void consumer() {
int value = future.get(); // Blocks until promise fulfilled
}Question 24
What is the difference between concurrent and parallel execution?
Question 25
What is the purpose of std::scoped_lock (C++17)?
std::mutex mtx1, mtx2;
void func() {
std::scoped_lock lock(mtx1, mtx2); // Locks both atomically
// No deadlock risk from lock ordering
}Question 26
What is the difference between thread synchronization and thread communication?
Question 27
What is the purpose of std::barrier (C++20)?
#include <barrier>
std::barrier barrier(3); // Wait for 3 threads
void worker() {
do_work();
barrier.arrive_and_wait(); // All threads sync here
do_more_work();
}Question 28
What is the difference between lock hierarchy and lock ordering?
Question 29
What is the purpose of std::latch (C++20)?
#include <latch>
std::latch latch(1); // Start with count 1
void worker() {
do_work();
latch.count_down(); // Decrement count
}
void main_thread() {
// Start workers
latch.wait(); // Wait for count to reach 0
// All workers done
}Question 30
What is the difference between thread affinity and thread migration?
Question 31
What is the purpose of std::semaphore (C++20)?
#include <semaphore>
std::counting_semaphore<5> semaphore(3); // Max 3 concurrent
void worker() {
semaphore.acquire(); // Wait for permit
do_work();
semaphore.release(); // Return permit
}Question 32
What is the difference between thread contention and thread starvation?
Question 33
What is the purpose of std::stop_token and std::stop_source (C++20)?
#include <stop_token>
std::stop_source source;
void worker(std::stop_token token) {
while (!token.stop_requested()) {
do_work();
if (should_stop()) break;
}
}
// Later...
source.request_stop(); // Signal all associated tokensQuestion 34
What is the difference between thread priority and thread scheduling?
Question 35
What is the purpose of std::atomic_ref (C++20)?
#include <atomic>
int value = 0;
std::atomic_ref<int> atomic_value(value);
void increment() {
atomic_value++; // Atomic operations on regular variable
}Question 36
What is the difference between thread pool and thread spawning?
Question 37
What is the purpose of std::execution (C++17/20)?
#include <execution>
#include <algorithm>
std::vector<int> data = {3, 1, 4, 1, 5};
// Sequential sort
std::sort(data.begin(), data.end());
// Parallel sort (if available)
std::sort(std::execution::par, data.begin(), data.end());Question 38
What is the difference between thread cancellation and thread termination?
Question 39
What is the purpose of std::hazard_pointer?
Question 40
What are the fundamental principles for effective concurrency in C++?
