C++ - Threading Utilities (C++20)

Overview

Estimated time: 60–80 minutes

Modern synchronization and lifetime helpers: jthread with automatic join, cooperative cancellation, latches/barriers for phase control, and semaphores for permits.

Learning Objectives

  • Use std::jthread for RAII-style threads and cooperative cancellation.
  • Coordinate threads with std::latch/std::barrier.
  • Throttle concurrency using std::counting_semaphore.

Prerequisites

jthread and stop_token

#include 
#include 
#include 
#include 

int main(){
  std::jthread worker([](std::stop_token st){
    using namespace std::chrono_literals;
    while(!st.stop_requested()){
      std::this_thread::sleep_for(10ms);
    }
    std::cout << "stopped\n";
  });
  worker.request_stop(); // cooperative cancel
} 

latch and barrier

#include 
#include 
#include 
#include 
#include 

int main(){
  std::latch start(1);
  std::barrier phase(4);
  std::vector threads;
  for (int i=0;i<3;++i){
    threads.emplace_back([&]{
      start.wait(); // all start together
      phase.arrive_and_wait(); // phase 1 done
      phase.arrive_and_wait(); // phase 2 done
    });
  }
  start.count_down();
  for (auto& t: threads) t.join();
  std::cout << "ok\n";
}

counting_semaphore

#include 
#include 
#include 
#include 

int main(){
  std::counting_semaphore sem(2); // 2 permits
  auto task=[&]{ sem.acquire(); std::cout<<"run\n"; sem.release(); };
  std::vector v(5);
  for(auto& t: v) t = std::thread(task);
  for(auto& t: v) t.join();
}

Common Pitfalls

  • Not checking stop_token regularly; cancellation stays cooperative.
  • Deadlocks with barriers if participant count mismatches arrivals.

Checks for Understanding

  1. How does jthread differ from thread?
  2. When to use a semaphore vs a mutex?
Show answers
  1. jthread joins automatically on destruction and carries a stop_token.
  2. Semaphore limits concurrency (permits), mutex protects critical sections.

Exercises

  1. Use jthread + stop_token to implement a cancellable periodic task.
  2. Limit concurrent downloads to N using counting_semaphore.