counting_semaphore

Semaphores, like mutexes, exclude threads from critical sections of code. Unlike mutexes, semaphores allow more than one thread to access the critical section at a time.

Semaphores are often used when N>1 threads are allowed to access a critical section at a time. Other threads are excluded until one of the resident threads exits the critical section.

::std::counting_semaphore contains a counter which decrements by one whenever counting_semaphore. acquire is called. The counter increases by one whenever counting_semaphore. release is called.

#include <iostream>
#include <syncstream>

#include <semaphore>
#include <thread>
#include <vector>

::std::counting_semaphore<3u>
   semaphore(3u);

void function(unsigned thread_index)
{
   semaphore.acquire();
   
   //
   // Only 3 threads are allowed in this section at a time:
   //
   
   ::std::osyncstream(::std::cout)
      << "Thread "
      << thread_index
      << " is in the critical section"
      << ::std::endl
         ;
   
   ::std::this_thread::sleep_for
      (
      ::std::chrono::seconds(3)
      )
      ;
   
   semaphore.release();
   
   return;
}

int main(int argc, char ** argv)
{
   ::std::vector
      <
      ::std::jthread
      >
      threads;
   
   unsigned const
      number_of_threads(10);
   
   for(unsigned i(0u); i< number_of_threads; ++i)
   {
      threads.emplace_back( function, i );
      
      continue;
   }
   
   return 0;
}
Possible output:
Thread 1 is in the critical section Thread 2 is in the critical section Thread 0 is in the critical section ... (pauses) ... Thread 3 is in the critical section Thread 4 is in the critical section Thread 6 is in the critical section ... (pauses) ... Thread 5 is in the critical section Thread 9 is in the critical section Thread 7 is in the critical section ... (pauses) ... Thread 8 is in the critical section

binary_semaphore

::std::binary_semaphore is an alias for ::std::counting_semaphore <1> . Implementations may specialize ::std::counting_semaphore <1> so that ::std::binary_semaphore is more efficient than a counting semaphore.