Search code examples
c++multithreadingsynchronizationc++11boost-thread

C++0x has no semaphores? How to synchronize threads?


Is it true that C++0x will come without semaphores? There are already some questions on Stack Overflow regarding the use of semaphores. I use them (posix semaphores) all the time to let a thread wait for some event in another thread:

void thread0(...)
{
  doSomething0();

  event1.wait();

  ...
}

void thread1(...)
{
  doSomething1();

  event1.post();

  ...
}

If I would do that with a mutex:

void thread0(...)
{
  doSomething0();

  event1.lock(); event1.unlock();

  ...
}

void thread1(...)
{
  event1.lock();

  doSomethingth1();

  event1.unlock();

  ...
}

Problem: It's ugly and it's not guaranteed that thread1 locks the mutex first (Given that the same thread should lock and unlock a mutex, you also can't lock event1 before thread0 and thread1 started).

So since boost doesn't have semaphores either, what is the simplest way to achieve the above?


Solution

  • You can easily build one from a mutex and a condition variable:

    #include <mutex>
    #include <condition_variable>
    
    class semaphore {
        std::mutex mutex_;
        std::condition_variable condition_;
        unsigned long count_ = 0; // Initialized as locked.
    
    public:
        void release() {
            std::lock_guard<decltype(mutex_)> lock(mutex_);
            ++count_;
            condition_.notify_one();
        }
    
        void acquire() {
            std::unique_lock<decltype(mutex_)> lock(mutex_);
            while(!count_) // Handle spurious wake-ups.
                condition_.wait(lock);
            --count_;
        }
    
        bool try_acquire() {
            std::lock_guard<decltype(mutex_)> lock(mutex_);
            if(count_) {
                --count_;
                return true;
            }
            return false;
        }
    };