std::counti...re::acquire(3) C++ Standard Libary std::counti...re::acquire(3) NAME std::counting_semaphore::acquire - std::counting_semaphore::acquire Synopsis 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 in- ternal counter. Preconditions (none) Parameters (none) Exceptions May throw std::system_error. 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_resolu- tion_clock> started_at; unsigned delay{rnd()}, occupy{rnd()}, wait_on_sema{}; public: static void start_time() { started_at = std::chrono::high_resolu- tion_clock::now(); } void initial_delay() { std::this_thread::sleep_for(delay * time_tick); } void occupy_sema() { wait_on_sema = static_cast<unsigned>(std::chrono::dura- tion_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("a", delay); cout_n("a", wait_on_sema); cout_n("a", occupy); std::cout << '\n'; } static void show_info() { std::cout << "\nThreads: " << max_threads << ", Throughput: " << max_sema_threads << " a Legend: initial delay aa a wait state aa a sema occupation aa \n" << std::endl; } }; std::array<Guide, max_threads> guides; void workerThread(unsigned id) { guides[id].initial_delay(); // emulate some work before sema acquisi- tion semaphore.acquire(); // wait until a free sema slot is avail- able guides[id].occupy_sema(); // emulate some work while sema is ac- quired 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 a Legend: initial delay aa a wait state aa a sema occupation aa # 1 aaaaaaaaaa # 2 aaaaaaaaaaaa # 5 aaaaaaaaaaaaaaaa # 8 aaaaaaaaaaaaaaaaaaaaaaaa # 9 aaaaaaaaaaaaaaaaaaaaaaaaaa # 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 6 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "Enough for everyone" case (no wait states!): max_threads{10U}, max_sema_threads{10} Threads: 10, Throughput: 10 a Legend: initial delay aa a wait state aa a sema occupation aa # 4 aaaaaaaaaa # 5 aaaaaaaaaa # 3 aaaaaaaaaaaaaa # 1 aaaaaaaaaaaaaa # 8 aaaaaaaaaaaaaaaaaaaa # 6 aaaaaaaaaaaaaaaaaaaaaa # 7 aaaaaaaaaaaaaaaaaaaaaa # 9 aaaaaaaaaaaaaaaaaaaaaaaaaa # 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Binary semaphore case: max_threads{10U}, max_sema_threads{1} Threads: 10, Throughput: 1 a Legend: initial delay aa a wait state aa a sema occupation aa # 6 aaaaaaaa # 5 aaaaaaaaaaaa # 4 aaaaaaaaaaaaaaaaaaaaaa # 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 0 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 1 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # 9 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa See also release increments the internal counter and unblocks acquirers (public member function) try_acquire tries to decrement the internal counter without block- ing (public member function) tries to decrement the internal counter, blocking for up to a try_acquire_for duration time (public member function) tries to decrement the internal counter, blocking un- til a point in try_acquire_until time (public member function) http://cppreference.com 2024.06.10 std::counti...re::acquire(3)
NAME | Synopsis | Preconditions | Parameters | Exceptions | Example | Possible output: | See also
Want to link to this manual page? Use this URL:
<https://man.FreeBSD.org/cgi/man.cgi?query=std::counting_semaphore::acquire&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>