std::counting_semaphore<LeastMaxValue>:: acquire
From cppreference.net
<
cpp
|
thread
|
counting semaphore
C++
Concurrency support library
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
std::counting_semaphore
| Member functions | ||||
| Operations | ||||
|
counting_semaphore::acquire
|
||||
| Constants | ||||
|
void
acquire
(
)
;
|
(自 C++20 起) | |
当内部计数器大于 0 时,原子性地将其递减 1 ;否则将阻塞直至计数器大于 0 并能成功递减内部计数器。
目录 |
前置条件
(无)
参数
(无)
异常
可能抛出 std::system_error 。
示例
本示例演示了多个随机化线程的并发工作场景:当活跃的线程函数数量不超过信号量的 期望值 N时,其他线程可能在信号量上等待。
运行此代码
#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(<span class="br
参见
|
递增内部计数器并解除获取者的阻塞
(公开成员函数) |
|
|
尝试非阻塞地递减内部计数器
(公开成员函数) |
|
|
尝试递减内部计数器,最多阻塞一段持续时间
(公开成员函数) |
|
|
尝试递减内部计数器,阻塞直到某个时间点
(公开成员函数) |