C++ Library - <semaphore>



The <semaphore> header in C++20, is used to control access to a shared resource by multiple threads. It is used in scenarios where to limit the number of threads that can access a section or shared resources simultaneously.

The <semaphore> can be in two states; binary semaphore or counting semaphore. Where a binary_semaphore allows a single thread to access a resource at a time, while counting_semaphore allows up to a certain number of threads. When the count reaches zero, the additional threads becomes blocked until the count gets greater than zero again.

The counting_semaphore holds an integer value, while binary_semaphore is limited to either 0 or 1

Including <semaphore> Header

To include the <semaphore> header in your C++ program, you can use the following syntax.

#include <semaphore>

Functions of <semaphore> Header

Below is list of all functions from <semaphore> header.

Sr.NoFunctions & Description
1release

It increments the internal counter and unblocks acquirers.

2acquire

It decrements the internal counter or blocks until it can.

3try_acquire

It tries to decrement the internal counter without blocking.

4try_acquire_for

It tries to decrement the internal counter, blocking for up to a duration time.

5try_acquire_until

It tries to decrement the internal counter, blocking until a point in time.

5max

It returns the maximum possible value of the internal counter.

Controlling the Access

In the following example, we are going to use the counting semaphore to limit access to a shared resource to a maximum of two threads at a time.

#include <iostream>
#include <semaphore>
#include <thread>
std::counting_semaphore < 2 > sem(2);
void a(int b) {
   sem.acquire();
   std::cout << "A" << b << " Accessing Resource.\n";
   std::this_thread::sleep_for(std::chrono::seconds(1));
   std::cout << "A" << b << " Releasing Resource.\n";
   sem.release();
}
int main() {
   std::thread x1(a, 1);
   std::thread x2(a, 2);
   std::thread x3(a, 3);
   x1.join();
   x2.join();
   x3.join();
   return 0;
}

Output

Output of the above code is as follows −

A1 Accessing Resource.
A2 Accessing Resource.
A1 Releasing Resource.
A3 Accessing Resource.
A2 Releasing Resource.
A3 Releasing Resource.