C++ Boost

Boost.Threads

semaphore


The semaphore class defines a classic synchronization primitive invented by the Dutch computer scientist Edsger W. Dijkstra. A semaphore manages an internal counter. This counter may never go below zero, or above a specified maximum value. When calling semaphore::down the calling thread will block until the value is non-zero and then decrements the value in a single atomic operation. When calling semaphore::up the calling thread will increment the value in a single atomic operation, failing if the value has already reached the specified maximum.

The semaphore is the simplest synchronization primitive available and is generally the primitive used to build other synchronization concepts at some level of implementation. For this reason Boost.Threads defines the semaphore type in the classic form. This simplifies usage and implementation, but it means that the interface is not as safe as other Boost.Threads interfaces. Unlike the mutex models supplied by Boost.Threads there is no lock_concept for the semaphore to help insure proper usage. Care should be taken when using a semaphore object to insure deadlock and race conditions do not occur.

Header

#include <boost/thread/semaphore.hpp>

Public Interface

    class semaphore : private boost::noncopyable
    {
    public:
        explicit semaphore(unsigned count=0, unsigned max=0);
        ~semaphore();
        
        bool up(unsigned count=1, unsigned* prev=0);
        void down();
        bool down(const xtime& xt);
    };

Constructor

    explicit semaphore(unsigned count=0, unsigned max=0);

Constructs a semaphore. The count parameter is used to set the initial semaphore count and the max parameter is used to set the maximum value for the semaphore. If max is 0 then the maximum value is set to the maximum possible value for the implementation.

Destructor

    ~semaphore();

Destructs a semaphore.

up

    bool up(unsigned count=1, unsigned* prev=0);

Increments the semaphore by count and optionally returns the previous value of the semaphore in prev. If the semaphore's value is already at the maximum value specified in the constructor then this operation fails immediately and returns a false value.

down

    void down();

Decrements the semaphore by one, blocking indefinately if the semaphore's value is currently zero.

    bool down(const xtime& xt);

Decrements the semaphore by one, blocking until xt if the semaphore's value is currently zero. If the operation times out a false value is returned.

Example Usage

#include <boost/thread/semaphore.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>

int global_data = 0;
boost::semaphore global_semaphore;

void change_global_data(void*)
{
    global_semaphore.down();
    ++global_data;
    std::cout << "global_data == " << global_data  << std::endl;
    global_semaphore.up();
}

int main(int, char*[])
{
    const int num_threads = 4;
    for (int i=0; i <  num_threads; ++i)
        boost::thread::create(&change_global_data, 0);
      
    boost::thread::join_all();
   
    return 0;
}

The output is:

global_data == 1
global_data == 2
global_data == 3
global_data == 4

Copyright William E. Kempf 2001 all rights reserved.