...

/

Signalling and Resource Counting Using Semaphores

Signalling and Resource Counting Using Semaphores

Learn how semaphores can be used for signaling and resource counting.

Semaphores

The word semaphore means something that can be used for signaling, such as a flag or a light. In the example that follows, we will see how we can use semaphores for signaling different states that other threads can be waiting for.

A semaphore can also be used to control access to a resource, similarly to how a std::mutex restricts access to a critical section:

Press + to interact
class Server {
public:
void handle(const Request& req) { sem_.acquire();
// Restricted section begins here.
// Handle at most 4 requests concurrently. do_handle(req);
sem_.release();
}
private:
void do_handle(const Request& req) { /* ... */ }
std::counting_semaphore<4> sem_{4};
};

In this case, the semaphore is initialized with a value of 4, which means that, at most, four concurrent requests can be handled at the same time. Instead of mutually exclusive access to a section in the code, multiple threads can have access to the same section but with restrictions concerning the number of threads currently in that section.

The member function acquire() decrements the semaphore if the semaphore is greater than zero. Otherwise, acquire() blocks until the semaphore allows it to decrement and enter the restricted section. release() increments the counter without blocking. If the semaphore was zero before it was incremented by release(), waiting threads will be signaled.

In addition to the acquire() function, it’s also possible to try to decrement the counter without blocking using the try_acquire() function. It returns true if it managed to decrement the counter, or false ...