Types of Semaphores

The <semaphores> header provides two types of semaphores that are:

1. std::counting_semaphore

A counting semaphore is a synchronization primitive that allows multiple threads to access a shared resource up to a certain limit.

  1. It is a generalization of a mutex or a binary semaphore.
  2. You can initialize a counting semaphore with an initial count, which represents the number of threads that can access the resource simultaneously without blocking.
  3. Threads can acquire and release counts, and the semaphore’s count is incremented or decremented accordingly.
  4. If a thread tries to acquire more counts than are available, it will block until counts become available.

Example

C++




// C++ Program to illustrate the use of counting_semaphore
#include <iostream>
#include <semaphore>
#include <thread>
using namespace std;
  
// Initialize semaphore with a count of 3
counting_semaphore<10> semaphore(3);
  
void worker(int id)
{
    // aquiring
    semaphore.acquire();
  
    // doing some work
    cout << "Thread " << id << " acquired the semaphore."
         << endl;
  
    // releasing
    semaphore.release();
    cout << "Thread " << id << " released the semaphore."
         << endl;
}
  
// driver code
int main()
{
    thread t1(worker, 1);
    thread t2(worker, 2);
    thread t3(worker, 3);
    t1.join();
    t2.join();
    t3.join();
    return 0;
}


Output

Thread 2 acquired the semaphore.
Thread 2 released the semaphore.
Thread 1 acquired the semaphore.
Thread 1 released the semaphore.
Thread 3 acquired the semaphore.
Thread 3 released the semaphore.

2. std::binary_semaphore

A binary semaphore is a simpler version of a semaphore that can have only two values: 0 and 1.

  1. It is often used for basic mutual exclusion or signaling between two threads.
  2. It can be thought of as a mutex with a more lightweight interface.

Example

C++




// C++ program to illustrate the binary semaphores
#include <iostream>
#include <semaphore>
#include <thread>
using namespace std;
  
// Initialize with a count of 1 (binary)
binary_semaphore semaphore(1);
  
void worker(int id)
{
    // aquire semaphore
    semaphore.acquire();
    cout << "Thread " << id << " acquired the semaphore."
         << endl;
  
    // Do some work
    semaphore.release();
    // release
    cout << "Thread " << id << " released the semaphore."
         << endl;
}
  
// driver code
int main()
{
    thread t1(worker, 1);
    thread t2(worker, 2);
    t1.join();
    t2.join();
    return 0;
}


Output

Thread 1 acquired the semaphore.
Thread 1 released the semaphore.
Thread 2 acquired the semaphore.
Thread 2 released the semaphore.

C++ 20 – Header

The C++20 <semaphore> header is part of the Concurrency Library Technical Specification (TS). Semaphores are synchronization primitives that help control access to shared resources in multi-threaded programs. The <semaphore> header provides the standard C++ way to work with semaphores.

In this article, we have covered important sections of semaphore headers such as the main classes, and usage of semaphore headers in C++20 along with examples.

Similar Reads

How to use in C++20?

Below is the step-by-step tutorial on the use of semaphores in C++ programs....

Types of Semaphores

The header provides two types of semaphores that are:...

Advantages of Semaphores

...

Contact Us