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.No | Functions & Description |
|---|---|
| 1 | release
It increments the internal counter and unblocks acquirers. |
| 2 | acquire
It decrements the internal counter or blocks until it can. |
| 3 | try_acquire
It tries to decrement the internal counter without blocking. |
| 4 | try_acquire_for
It tries to decrement the internal counter, blocking for up to a duration time. |
| 5 | try_acquire_until
It tries to decrement the internal counter, blocking until a point in time. |
| 5 | max
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.