# tf::Semaphore class
#include <taskflow/core/semaphore.hpp>

class to create a semophore object for building a concurrency constraint

A semaphore creates a constraint that limits the maximum concurrency, i.e., the number of workers, in a set of tasks. You can let a task acquire/release one or multiple semaphores before/after executing its work. A task can acquire and release a semaphore, or just acquire or just release it. A tf::Semaphore object starts with an initial count. As long as that count is above 0, tasks can acquire the semaphore and do their work. If the count is 0 or less, a task trying to acquire the semaphore will not run but goes to a waiting list of that semaphore. When the semaphore is released by another task, it reschedules all tasks on that waiting list.

    tf::Executor executor(8);   // create an executor of 8 workers
    tf::Taskflow taskflow;

    tf::Semaphore semaphore(1); // create a semaphore with initial count 1

    for(size_t i=0; i<1000; i++) {
      taskflow.emplace([&](tf::Runtime& rt){
        rt.acquire(semaphore);
        std::cout << "critical section here (one worker at any time)\n";
        critical_section();
        rt.release(semaphore);
      });
    }

    executor.run(taskflow).wait();

The above example creates a taskflow of 1000 independent tasks while only one worker will run `critical_section` at any time due to the semaphore constraint. This arrangement limits the parallelism of `critical_section` to just one.

#### Note

Taskflow use a non-blocking algorithm to implement the acquisition of semaphores and thus is deadlock-free.

## Constructors, destructors, conversion operators

Semaphore()
  constructs a default semaphore with count equal to zero
Semaphore(size_t count) explicit
  constructs a semaphore with the given count

## Public functions

auto count(std::memory_order memory_order = std::memory_order_seq_cst) const -> size_t
  queries the current value of the associated counter
auto try_acquire() -> bool
  tries to atomically decrement the internal counter by `1` if it is greater than `0`
void release(size_t n = 1)
  atomically increment the internal counter by `n`
void reset(size_t count, std::memory_order memory_order = std::memory_order_seq_cst)
  resets the semaphore to the given count

## Function documentation

### tf::Semaphore:: Semaphore()

constructs a default semaphore with count equal to zero

Application can use tf::Semaphore::reset to reset the counter of the semaphore later.

### tf::Semaphore:: Semaphore(size_t count) explicit

constructs a semaphore with the given count

A semaphore creates a constraint that limits the maximum concurrency, i.e., the number of workers, in a set of tasks.

    tf::Semaphore semaphore(4);  // a semaphore initialized with 4

### size_t tf::Semaphore:: count(std::memory_order memory_order = std::memory_order_seq_cst) const

queries the current value of the associated counter

Parameters
memory_order | the memory order of this load (default std::memory_order_seq_cst)

Queries the current value of the associated counter.

### bool tf::Semaphore:: try_acquire()

tries to atomically decrement the internal counter by `1` if it is greater than `0`

Returns | `true` if it decremented the internal counter, otherwise `false`

Tries to atomically decrement the internal counter by `1`. If the operation succeeds, returns `true`, otherwise `false`.

### void tf::Semaphore:: release(size_t n = 1)

atomically increment the internal counter by `n`

Parameters
n | the value by which the internal counter will be incremented

The release operation always succeeds as it simply increments the counter of this semaphore.

### void tf::Semaphore:: reset(size_t count, std::memory_order memory_order = std::memory_order_seq_cst)

resets the semaphore to the given count

Parameters
count | the new count value
memory_order | memory order to which this operation will be applied (default std::memory_order_seq_cst)

#### Note

Calling tf::Semaphore::reset will immediately change the underlying counter to the given `count` value, regardless other threads acquiring or releasing the semaphore.

Tab / T to search, Esc to close
…

Search for symbols, directories, files, pages or modules. You can omit any prefix from the symbol or file path; adding a `:` or `/` suffix lists all members of given symbol or directory.

Use ↓ / ↑ to navigate through the list, Enter to go. Tab autocompletes common prefix, you can copy a link to the result using ⌘ L while ⌘ M produces a Markdown link.

Sorry, nothing was found.