Namespaces
Variants

std::counting_semaphore<LeastMaxValue>:: acquire

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
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

参见

递增内部计数器并解除获取者的阻塞
(公开成员函数)
尝试非阻塞地递减内部计数器
(公开成员函数)
尝试递减内部计数器,最多阻塞一段持续时间
(公开成员函数)
尝试递减内部计数器,阻塞直到某个时间点
(公开成员函数)