Spec-Zone.ru › C++

std::counting_semaphore, std::binary_semaphore

Определено в заголовке <semaphore>
template< std::ptrdiff_t LeastMaxValue = /* implementation-defined */ >
class counting_semaphore;
(1) (с C++20)
using binary_semaphore = std::counting_semaphore<1>;
(2) (с C++20)
1) Счётный семафор — это лёгкий механизм синхронизации, который может управлять доступом к общим ресурсам. В отличие от бинарного семафора, счётный семафор позволяет более чем одному одновременному доступу к тому же ресурсу, по крайней мере, для LeastMaxValue одновременных пользователей. Программа неверна, если LeastMaxValue отрицательно.
2) binary_semaphore — это псевдоним для специализации std::counting_semaphore, где LeastMaxValue равно 1. Реализации могут реализовать binary_semaphore более эффективно, чем по умолчанию для std::counting_semaphore.

Счётный семафор содержит внутренний счётчик, инициализированный конструктором. Этот счётчик уменьшается при вызовах acquire() и связанных с ним методах, и увеличивается при вызовах release(). Когда счётчик равен нулю, acquire() блокируется до тех пор, пока счётчик не увеличится, но try_acquire() не блокируется; try_acquire_for() и try_acquire_until() блокируются до тех пор, пока счётчик не увеличится или не будет достигнут таймаут.

Аналогично std::condition_variable::wait(), случайная неудача возможна в работе counting_semaphore с try_acquire().

Специализации std::counting_semaphore не являются DefaultConstructible, CopyConstructible, MoveConstructible, CopyAssignable или MoveAssignable.

Члены-функции

(конструктор)
создаёт счётный семафор
(публичный член-функция)
(деструктор)
уничтожает счётный семафор
(публичный член-функция)
operator=
[удалено]
Присвоение счётного семафора недоступно
(публичный член-функция)
Операции
release
увеличивает внутренний счётчик и разблокирует ожидающих доступа
(публичный член-функция)
acquire
уменьшает внутренний счётчик или блокируется до тех пор, пока это возможно
(публичный член-функция)
try_acquire
пытается уменьшить внутренний счётчик, не блокируясь
(публичный член-функция)
try_acquire_for
пытается уменьшить внутренний счётчик, блокируясь на заданный период времени
(публичный член-функция)
try_acquire_until
пытается уменьшить внутренний счётчик, блокируясь до заданного момента времени
(публичный член-функция)
Константы
max
[статический]
возвращает максимально возможное значение внутреннего счётчика
(публичная статическая член-функция)

Примечания

Как следует из названия, LeastMaxValue — это минимальное максимальное значение, а не фактическое максимальное значение. Поэтому max() может дать число, большее, чем LeastMaxValue.

В отличие от std::mutex, счётный семафор не привязан к потокам выполнения — получение семафора может происходить в одном потоке, а освобождение — в другом, например. Все операции со счётным семафором могут выполняться параллельно и не зависят от конкретных потоков выполнения, за исключением деструктора, который не может выполняться параллельно, но может выполняться в другом потоке.

Семафоры также часто используются для семантики сигнализации/уведомления, а не взаимной исключительности, инициализируя семафор значением ​0​ и тем самым блокируя получателя(ей), пытающегося acquire(), пока уведомление не «сигнализирует», вызвав release(n). В этом отношении семафоры могут рассматриваться как альтернатива std::condition_variable с лучшей производительностью.

Макро-тест функции Значение Std Функция
__cpp_lib_semaphore 201907L (C++20) std::counting_semaphore, std::binary_semaphore

Пример

#include <chrono>
#include <iostream>
#include <semaphore>
#include <thread>
 
// global binary semaphore instances
// object counts are set to zero
// objects are in non-signaled state
std::binary_semaphore
    smphSignalMainToThread{0},
    smphSignalThreadToMain{0};
 
void ThreadProc()
{
    // wait for a signal from the main proc
    // by attempting to decrement the semaphore
    smphSignalMainToThread.acquire();
 
    // this call blocks until the semaphore's count
    // is increased from the main proc
 
    std::cout << "[thread] Got the signal\n"; // response message
 
    // wait for 3 seconds to imitate some work
    // being done by the thread
    using namespace std::literals;
    std::this_thread::sleep_for(3s);
 
    std::cout << "[thread] Send the signal\n"; // message
 
    // signal the main proc back
    smphSignalThreadToMain.release();
}
 
int main()
{
    // create some worker thread
    std::thread thrWorker(ThreadProc);
 
    std::cout << "[main] Send the signal\n"; // message
 
    // signal the worker thread to start working
    // by increasing the semaphore's count
    smphSignalMainToThread.release();
 
    // wait until the worker thread is done doing the work
    // by attempting to decrement the semaphore's count
    smphSignalThreadToMain.acquire();
 
    std::cout << "[main] Got the signal\n"; // response message
    thrWorker.join();
}

Вывод:

[main] Send the signal
[thread] Got the signal
[thread] Send the signal
[main] Got the signal

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/thread/counting_semaphore

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API