Espacios de nombres
Variantes

std::counting_semaphore<LeastMaxValue>::acquire

De cppreference.com
 
 
Biblioteca de apoyo de concurrencia
Hilos
(C++11)
(C++20)
Espacio de nombres this_thread
(C++11)
(C++11)
(C++11)
CancelaciΓ³n cooperativa
ExclusiΓ³n mutua
(C++11)
GestiΓ³n genΓ©rica de bloqueo
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Variables de condiciΓ³n
(C++11)
SemΓ‘foros
Pestillos y barreras
(C++20)
(C++20)
Futuros
(C++11)
(C++11)
(C++11)
(C++11)
RecuperaciΓ³n segura
(C++26)
Punteros de riesgo
Tipos atΓ³micos
(C++11)
(C++20)
InicializaciΓ³n de tipos atΓ³micos
(C++11)(en desuso en C++20)
(C++11)(en desuso en C++20)
Orden de memoria
Funciones independientes para operaciones atΓ³micas
Funciones independientes para indicadores atΓ³micos
 
 
void acquire();
(desde C++20)

Disminuye atΓ³micamente el contador interno en 1 si es mayor que 0; de lo contrario, se bloquea hasta que sea mayor que 0 y pueda disminuir con Γ©xito el contador interno.

Precondiciones

(Ninguna)

ParΓ‘metros

(Ninguno)

Excepciones

Puede lanzar std::system_error.

Ejemplo

El ejemplo visualiza un trabajo concurrente de varios hilos aleatorios cuando no mΓ‘s de N (N es el valor del semΓ‘foro desired) de las funciones del hilo estΓ‘n activas, mientras que el otro podrΓ­a esperar por el semΓ‘foro.

#include <array>
#include <chrono>
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <random>
#include <semaphore>
#include <thread>
#include <vector>
using namespace std::literals;

constexpr std::size_t       max_threads{10U}; // cambiar y ver el efecto
constexpr std::ptrdiff_t    max_sema_threads{3}; // {1} para semΓ‘foro binario
std::counting_semaphore     semaphore{max_sema_threads};
constexpr auto              time_tick{10ms};

unsigned rnd() {
    static std::uniform_int_distribution<unsigned> distribution{2U, 9U}; // [retrasos]
    static std::random_device engine;
    static std::mt19937 noise{engine()};
    return distribution(noise);
}

class alignas( 128 /*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) {
            n *= x_scale;
            while (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
            << "\nHilos: " << max_threads << ", Rendimiento: " << max_sema_threads
            << " β”‚ Leyenda: retraso inicial β–‘β–‘ β”‚ edo. espera β–’β–’ β”‚ ocupaciΓ³n sema β–ˆβ–ˆ \n"
            << std::endl;
    }
};

std::array<Guide, max_threads> guides;

void workerThread(unsigned id) {
    guides[id].initial_delay(); // emular trabajo antes adquisiciΓ³n semΓ‘foro
    semaphore.acquire();        // esperar hasta que ranura semΓ‘foro estΓ© disponible
    guides[id].occupy_sema();   // emular trabajo mientras semΓ‘foro se adquiere
    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));
    }
}

Posible salida:

Caso por defecto: max_threads{10U}, max_sema_threads{3}

Hilos: 10, Rendimiento: 3 β”‚ Leyenda: retraso inicial β–‘β–‘ β”‚ edo. espera β–’β–’ β”‚ ocupaciΓ³n sema β–ˆβ–ˆ

# 1 β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 2 β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 5 β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 8 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 9 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 7 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 4 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 6 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 3 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 0 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ

──────────────────────────────────────────────────────────────────────────────────────────────────────────────
Caso "suficiente para todos" (sin edos. de espera!): max_threads{10U}, max_sema_threads{10}

Hilos: 10, Rendimiento: 10 β”‚ Leyenda: retraso inicial β–‘β–‘ β”‚ edo. espera β–’β–’ β”‚ ocupaciΓ³n sema β–ˆβ–ˆ

# 4 β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 5 β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆ
# 3 β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 1 β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 8 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 6 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 7 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 9 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 0 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 2 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ

──────────────────────────────────────────────────────────────────────────────────────────────────────────────
Caso semΓ‘foro binario: max_threads{10U}, max_sema_threads{1}

Hilos: 10, Rendimiento: 1 β”‚ Leyenda: retraso inicial β–‘β–‘ β”‚ edo. espera β–’β–’ β”‚ ocupaciΓ³n sema β–ˆβ–ˆ

# 6 β–‘β–‘β–‘β–‘β–ˆβ–ˆβ–ˆβ–ˆ
# 5 β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆ
# 4 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 7 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 2 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 3 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 0 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 1 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 8 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ
# 9 β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ