Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bslmt_semaphore
[Package bslmt]

Provide a semaphore class. More...

Namespaces

namespace  bslmt

Detailed Description

Outline
Purpose:
Provide a semaphore class.
Classes:
bslmt::Semaphore semaphore class
See also:
Component bslmt_timedsemaphore
Description:
This component defines a portable and efficient thread synchronization primitive. In particular, bslmt::Semaphore is an efficient synchronization primitive that enables sharing of a counted number of resources or exclusive access. The usage model of this facility is modeled on POSIX semaphores and Windows semaphores.
Usage:
This example illustrates a very simple queue where potential clients can push integers to a queue, and later retrieve the integer values from the queue in FIFO order. It illustrates two potential uses of semaphores: to enforce exclusive access, and to allow resource sharing.
  class IntQueue {
      // FIFO queue of integer values.

      // DATA
      bsl::deque<int> d_queue;        // underlying queue
      bslmt::Semaphore d_mutexSem;     // mutual-access semaphore
      bslmt::Semaphore d_resourceSem;  // resource-availability semaphore

      // NOT IMPLEMENTED
      IntQueue(const IntQueue&);
      IntQueue& operator=(const IntQueue&);

    public:
      // CREATORS
      explicit IntQueue(bslma::Allocator *basicAllocator = 0);
          // Create an 'IntQueue' object.  Optionally specified a
          // 'basicAllocator' used to supply memory.  If 'basicAllocator' is
          // 0, the currently installed default allocator is used.

      ~IntQueue();
          // Destroy this 'IntQueue' object.

      // MANIPULATORS
      int getInt();
          // Retrieve an integer from this 'IntQueue' object.  Integer values
          // are obtained from the queue in FIFO order.

      void pushInt(int value);
          // Push the specified 'value' to this 'IntQueue' object.
  };
Note that the IntQueue constructor increments the count of the semaphore to 1 so that values can be pushed into the queue immediately following construction:
  // CREATORS
  IntQueue::IntQueue(bslma::Allocator *basicAllocator)
  : d_queue(basicAllocator)
  {
      d_mutexSem.post();
  }

  IntQueue::~IntQueue()
  {
      d_mutexSem.wait();  // Wait for potential modifier.
  }

  // MANIPULATORS
  int IntQueue::getInt()
  {
      // Waiting for resources.
      d_resourceSem.wait();

      // 'd_mutexSem' is used for exclusive access.
      d_mutexSem.wait();        // lock
      const int ret = d_queue.back();
      d_queue.pop_back();
      d_mutexSem.post();        // unlock

      return ret;
  }

  void IntQueue::pushInt(int value)
  {
      d_mutexSem.wait();
      d_queue.push_front(value);
      d_mutexSem.post();

      d_resourceSem.post();  // Signal we have resources available.
  }