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(); }