---
name: "semaphore"
section: "3bobcat"
platform: "linux"
package: "libbobcat-dev"
version: "6.07.01-2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/semaphore"
---

# semaphore(3bobcat)

Implements the Semaphore type designed by Dijkstra

## NAME

FBB::Semaphore - Implements the Semaphore type designed by Dijkstra

## SYNOPSIS

**#include \<bobcat/semaphore\>**\

Linking option: *-lpthread -lbobcat*

## DESCRIPTION

According to *http://en.wikipedia.org/wiki/Semaphore\_(programming)* a semaphore is a variable or abstract data type that is used for controlling access, by multiple processes, to a common resource in a parallel programming or a multi user environment. The *Semaphore* as a data type was designed around 1962 by Edsger Dijkstra.

A useful way to think of a semaphore is as a record of how many units of a particular resource are available, coupled with operations to safely (i.e., without race conditions) adjust that record as units are required or become free, and, if necessary, wait until a unit of the resource becomes available.

Semaphores are a useful tool in the prevention of race conditions.  Semaphores allowing an arbitrary resource count are called counting semaphores, while semaphores which are restricted to the values 0 and 1 (or locked/unlocked, unavailable/available) are called binary semaphores. Both types are supported by Bobcat’s implementation.

## NAMESPACE

**FBB**\
 All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace **FBB**.

## INHERITS FROM

\-

## CONSTRUCTORS

- o

  **Semaphore(size\_t nAvailable)**:\
   The constructor defines the semaphore’s initial state. With a counting semaphore *nAvailable* defines, e.g., the number of available locations in a storage area. Locking/unlocking, supporting facilities to notify other waiting threads is implemented via binary semaphores, which are initialized to 1 or 0. A semaphore containing the value 0 blocks. I.e., its *wait* member waits until its value is incremented by another thread, calling one of the semaphore’s *notify* members.

Copy and move constructors (and assignment operators) are not available.

## MEMBER FUNCTIONS

- o

  **void notify()**:\
   The internally maintained *available* value is incremented and one waiting thread (cf. the *wait* members below) is notified, reactivating that thread.

- o

  **void notify\_all()**:\
   The internally maintained *available* value is incremented and all waiting threads (cf. the *wait* members below) are notified. Only one waiting thread will be able to obtain the semaphore’s lock and to reduce *available*, and that particular thread is thereupon reactivated.

- o

  **void set(size\_t available)**:\
   This member blocks until it has obtained the lock of the *std::mutex* which is maintained internally by the *Semaphore* object. Next the *Semaphore’s available* value receives the value of the member’s argument, and the lock is released.

- o

  **size\_t size() const**:\
   Without trying to lock the *Semaphore* object’s *mutex* the current value of the *Semaphore’s available* value is returned.

- o

  **void wait()**:\
   This member blocks for as long as the internally stored value (*available*) equals zero. When returning from *wait* the current thread holds the lock of the *std::mutex* which is maintained internally by the *Semaphore* object. *Notify* members are used to increment *available* and to inform *wait* that it may return. When multiple threads are waiting only one thread will stop waiting, while the remaining threads will continue to wait for another notification.

- o

  **bool wait(Fun fun, Params &&...args)**:\
   This is a member template, where *Fun* is a function (object) receiving the argument passed to *wait*, and returning a *bool*. This member blocks until it has obtained the *Semaphore’s* mutex lock, then, while its *available* value equals 0, waits until being notified. Once it has reacquired the lock after being notified *fun* is called, receiving *wait’s* perfectly forwarded remaining arguments. This member returns *false* if *fun* returns *false*. It returns *true* if *fun* returns *true* and *available* was unequal zero following *fun* returning *true*. The function may therefore perform tasks outside of the *Semaphore* local environment, which might even involve updating the *Semaphore’s* *available* value.

- o

  **std::cv\_status wait\_for(std::chrono::duration\<Rep, Period\> const** **&relTime)**:\
   This member blocks for as long as the internally stored value (*available*) equals zero and the amount of time specified by *relTime* hasn’t passed. If the latter happens, *std::cv\_status::timeout* is returned, otherwise *std::cv\_status::no\_timeout* is returned, in which case the current thread holds the lock of the *std::mutex* which is maintained internally by the *Semaphore* object. *Notify* members are used to increment *available* and to inform *wait* that it may return. When multiple threads are waiting only one thread will stop waiting, while the remaining threads will continue to wait for another notification.

- o

  **std::cv\_status wait\_until(std::chrono::time\_point\<Clock, Duration\>** **const &absTime)**:\
   This member blocks for as long as the internally stored value (*available*) equals zero and the time specified by *absTime* hasn’t been reached. If the latter happens (or if *absTime* lies in the past) *std::cv\_status::timeout* is returned, otherwise *std::cv\_status::no\_timeout* is returned, in which case the current thread holds the lock of the *std::mutex* which is maintained internally by the *Semaphore* object. *Notify* members are used to increment *available* and to inform *wait* that it may return. When multiple threads are waiting only one thread will stop waiting, while the remaining threads will continue to wait for another notification.

## EXAMPLE

```
    #include <bobcat/semaphore>
    using namespace FBB;
    Semaphore produce(10);          // storage area size
    Semaphore consume(0);           // # items in store
    std::queue itemQueue;           // storage queue
    void consumer()
    {
        while (true)
        {
            consume.wait();          // wait until there’s an item in store
                // mutex lock the queue with multiple consumers
            size_t item = itemQueue.front();
            itemQueue.pop();
            produce.notify();   // notify the producer
            process(item);      // not implemented
        }
    }
    void producer()
    {
        size_t item = 0;
        while (true)
        {
            ++item;
            produce.wait();     // wait for room in the storage
                // mutex lock the queue with multiple consumers
            itemQueue.push(item);
            consume.notify();   // notify the consumer
        }
    }
    int main()
    {
        thread cons(consumer);
        thread prod(producer);
        cons.join();            // ending the threads not implemented
        prod.join();
    }
```

## FILES

*bobcat/semaphore* - defines the class interface

## SEE ALSO

[**bobcat**(7)](/bobcat/7.md)

## BUGS

None Reported.

## BOBCAT PROJECT FILES

- o

  *https://fbb-git.gitlab.io/bobcat/*: gitlab project page;

Debian Bobcat project files:

- o

  *libbobcat6*: debian package containing the shared library, changelog and copyright note;

- o

  *libbobcat-dev*: debian package containing the static library, headers, manual pages, and developer info;

## BOBCAT

Bobcat is an acronym of \`Brokken’s Own Base Classes And Templates’.

## COPYRIGHT

This is free software, distributed under the terms of the GNU General Public License (GPL).

## AUTHOR

Frank B. Brokken (**f.b.brokken@rug.nl**).
