FBB::Semaphore(3bobcat)
Dijkstra's Semaphore
(libbobcat-dev_6.06.02)
2005-2024
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
    
    -  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
    
    -  void notify():
 The internally maintained available value is incremented and one
        waiting thread (cf. the wait members below) is notified,
        reactivating that thread.
-  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.
-  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.
-  size_t size() const:
 Without trying to lock the Semaphore object's mutex the current
        value of the Semaphore's available value is returned.
-  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.
-  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.
-  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.
-  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)
BUGS
    None Reported.
BOBCAT PROJECT FILES
    -  https://fbb-git.gitlab.io/bobcat/: gitlab project page;
    
-  bobcat_6.06.02-x.dsc: detached signature;
    
-  bobcat_6.06.02-x.tar.gz: source archive;
    
-  bobcat_6.06.02-x_i386.changes: change log;
    
-  libbobcat1_6.06.02-x_*.deb: debian package containing the
            libraries;
    
-  libbobcat1-dev_6.06.02-x_*.deb: debian package containing the
            libraries, headers and manual pages;
    
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).