A semaphore object is a synchronization object that maintains a count between zero and a specified maximum value. The count is decremented each time a thread completes a wait for the semaphore object and incremented each time a thread releases the semaphore. When the count reaches zero, no more threads can successfully wait for the semaphore object state to become signaled. The state of a semaphore is set to signaled when its count is greater than zero, and nonsignaled when its count is zero. It is a generalized mutex. In lieu of single buffer, we can split the 4 KB buffer into four 1 KB buffers (identical resources). It can be associated with these four buffers. The consumer and producer can work on different buffers at the same time. The following example is a semaphore for C++ applications.
#pragma once
#include <mutex>
#include <condition_variable>
class Semaphore
{
public:
explicit Semaphore(int init_count = count_max) : count_(init_count) {}
void wait();
void lock();
void signal();
void unlock();
bool try_wait();
bool try_lock();
private:
int count_;
std::mutex m_;
std::condition_variable cv_;
static const int count_max = 1;
};
#include "Semaphore.h"
void Semaphore::wait()
{
std::unique_lock<std::mutex> lk(m_);
cv_.wait(lk, [=]{ return 0 < count_; });
--count_;
}
bool Semaphore::try_wait()
{
std::lock_guard<std::mutex> lk(m_);
if (0 < count_) {
--count_;
return true;
}
else {
return false;
}
}
void Semaphore::signal()
{
std::lock_guard<std::mutex> lk(m_);
if (count_ < count_max) {
++count_;
cv_.notify_one();
}
}
void Semaphore::lock()
{
wait();
}
bool Semaphore::try_lock()
{
return try_wait();
}
void Semaphore::unlock()
{
signal();
}