std::counting_semaphore<LeastMaxValue>::acquire
From cppreference.com
< cpp | thread | counting semaphore
C++
Feature test macros (C++20)
Concepts library (C++20)
Metaprogramming library (C++11)
Ranges library (C++20)
Filesystem library (C++17)
Concurrency support library (C++11)
Execution control library (C++26)
Concurrency support library
(C++11)
(C++20)
(C++11)
(C++11)
(C++20)
(C++26)
(C++26)
(C++20)
(C++26)
(C++20)
(C++26)
(C++26)
(C++26)
(C++26)
(C++26)
(C++26)
(C++11)
(C++11)
(C++17)
(C++11)
(C++14)
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)(C++11)(C++11)(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++20)(C++20)
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
(C++26)
(C++26)
(C++26)
(C++11)
(C++20)
(C++11)
(C++11)(deprecated in C++20)
(C++11)(deprecated in C++20)
(C++11)
(C++11)
(C++11)(deprecated in C++26)
(C++11)
(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)
(C++26)(C++26)
(C++26)(C++26)
(C++11)
(C++20)(C++20)
(C++20)
(C++20)
(C++11)(C++11)
(C++11)(C++11)
(C++20)(C++20)
(C++20)(C++20)
(C++20)
(C++20)
std::counting_semaphore
Member functions
Operations
counting_semaphore::acquire
Constants
void acquire();
(since C++20)
Atomically decrements the internal counter by 1 if it is greater than 0; otherwise blocks until it is greater than 0 and can successfully decrement the internal counter.
[edit] Preconditions
(none)
[edit] Parameters
(none)
[edit] Exceptions
May throw std::system_error .
[edit] Example
The example visualizes a concurrent work of several randomized threads when no more than N (N is the semaphore desired value) of the thread-functions are active, while the other might wait on the semaphore.
Run this code
#include <array> #include <chrono> #include <cstddef> #include <iomanip> #include <iostream> #include <mutex> #include <new> #include <random> #include <semaphore> #include <thread> #include <vector> using namespace std::literals; constexpr std::size_t max_threads{10U}; // change and see the effect constexpr std::ptrdiff_t max_sema_threads{3}; // {1} for binary semaphore std::counting_semaphore semaphore{max_sema_threads}; constexpr auto time_tick{10ms}; unsigned rnd() { static std::uniform_int_distribution <unsigned> distribution{2U, 9U}; // [delays] static std::random_device engine; static std::mt19937 noise{engine()}; return distribution(noise); } class alignas(std::hardware_destructive_interference_size ) Guide { inline static std::mutex cout_mutex; inline static std::chrono::time_point <std::chrono::high_resolution_clock > started_at; unsigned delay{rnd()}, occupy{rnd()}, wait_on_sema{}; public: static void start_time() { started_at = std::chrono::high_resolution_clock::now (); } void initial_delay() { std::this_thread::sleep_for (delay * time_tick); } void occupy_sema() { wait_on_sema = static_cast<unsigned>(std::chrono::duration_cast <std::chrono::milliseconds >( std::chrono::high_resolution_clock::now () - started_at - delay * time_tick).count() / time_tick.count()); std::this_thread::sleep_for (occupy * time_tick); } void visualize(unsigned id, unsigned x_scale = 2) const { auto cout_n = [=](auto str, unsigned n) { for (n *= x_scale; n-- > 0; std::cout << str) ; }; std::lock_guard lk{cout_mutex}; std::cout << '#' << std::setw (2) << id << ' '; cout_n("░", delay); cout_n("▒", wait_on_sema); cout_n("█", occupy); std::cout << '\n'; } static void show_info() { std::cout << "\nThreads: " << max_threads << ", Throughput: " << max_sema_threads << " │ Legend: initial delay ░░ │ wait state ▒▒ │ sema occupation ██ \n" << std::endl ; } }; std::array <Guide, max_threads> guides; void workerThread(unsigned id) { guides[id].initial_delay(); // emulate some work before sema acquisition semaphore.acquire(); // wait until a free sema slot is available guides[id].occupy_sema(); // emulate some work while sema is acquired semaphore.release(); guides[id].visualize(id); } int main() { std::vector <std::jthread > threads; threads.reserve(max_threads); Guide::show_info(); Guide::start_time(); for (auto id{0U}; id != max_threads; ++id) threads.push_back(std::jthread (workerThread, id)); }
Possible output:
Default case: max_threads{10U}, max_sema_threads{3}
Threads: 10, Throughput: 3 │ Legend: initial delay ░░ │ wait state ▒▒ │ sema occupation ██
# 1 ░░░░██████
# 2 ░░░░████████
# 5 ░░░░░░██████████
# 8 ░░░░░░░░░░░░████████████
# 9 ░░░░░░░░░░░░██████████████
# 7 ░░░░░░░░░░░░▒▒▒▒████████████████
# 4 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒████████
# 6 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒██████████████████
# 3 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████
# 0 ░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
"Enough for everyone" case (no wait states!): max_threads{10U}, max_sema_threads{10}
Threads: 10, Throughput: 10 │ Legend: initial delay ░░ │ wait state ▒▒ │ sema occupation ██
# 4 ░░░░██████
# 5 ░░░░░░████
# 3 ░░░░██████████
# 1 ░░░░██████████
# 8 ░░░░░░░░████████████
# 6 ░░░░░░░░░░░░░░░░██████
# 7 ░░░░░░░░░░░░░░░░██████
# 9 ░░░░░░░░░░░░░░░░██████████
# 0 ░░░░░░░░░░░░██████████████████
# 2 ░░░░░░░░░░░░░░░░░░████████████
──────────────────────────────────────────────────────────────────────────────────────────────────────────────
Binary semaphore case: max_threads{10U}, max_sema_threads{1}
Threads: 10, Throughput: 1 │ Legend: initial delay ░░ │ wait state ▒▒ │ sema occupation ██
# 6 ░░░░████
# 5 ░░░░▒▒▒▒████
# 4 ░░░░░░░░░░▒▒██████████
# 7 ░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒████████████████
# 2 ░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████
# 3 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████████
# 0 ░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████████
# 1 ░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████
# 8 ░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████
# 9 ░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████████[edit] See also
tries to decrement the internal counter, blocking for up to a duration time
(public member function) [edit]
(public member function) [edit]
tries to decrement the internal counter, blocking until a point in time
(public member function) [edit]
(public member function) [edit]