std::counti...ry_semaphore(3)
π NAME π
okay so bestie, this is the std::counting_semaphore / std::binary_semaphore page from the C++ Standard Libary manual, title std::counti...ry_semaphore(3) β and we are absolutely getting into semaphore lore today. π¦
the NAME line is literally std::counting_semaphore,std::binary_semaphore β std::counting_semaphore,std::binary_semaphore (yes, it repeats itself, she's quirky like that π
).
β¨ Synopsis β¨
Defined in header <semaphore>
template< std::ptrdiff_t LeastMaxValue = /* implementation-defined
*/ >
(1) (since C++20)
class counting_semaphore;
using binary_semaphore = std::counting_semaphore<1>;
(2) (since C++20)
- A
counting_semaphoreis a lightweight synchronization primitive that can control access to a shared resource. Unlike astd::mutex, acounting_semaphoreallows more than one concurrent access to the same resource, for at leastLeastMaxValueconcurrent accessors. the program is ill-formed ifLeastMaxValueis negative β do not test her on this, bestie, it's giving undefined-adjacent bad vibes. π binary_semaphoreis an alias for specialization ofstd::counting_semaphorewithLeastMaxValuebeing1. Implementations may implementbinary_semaphoremore efficiently than the default implementation ofstd::counting_semaphore. π
A counting_semaphore contains an internal counter initialized by the constructor. This counter is decremented by calls to acquire() and related methods, and is incremented by calls to release(). When the counter is zero, acquire() blocks until the counter is incremented, but try_acquire() does not block; try_acquire_for() and try_acquire_until() block until the counter is incremented or a timeout is reached. β¨
Similar to std::condition_variable::wait(), counting_semaphore's try_acquire() can spuriously fail. yes, she can randomly fail, it's not you, it's the semaphore π«
Specializations of std::counting_semaphore are not DefaultConstructible, CopyConstructible, MoveConstructible, CopyAssignable, or MoveAssignable. no copying, no moving, no assigning β she is not a shareable vibe, okay? π
π Member functions π
constructorβ constructs acounting_semaphore(public member function)destructorβ destructs thecounting_semaphore(public member function)operator=βcounting_semaphoreis not assignable[deleted](public member function)
π₯ Operations π₯
releaseβ increments the internal counter and unblocks acquirers (public member function)acquireβ decrements the internal counter or blocks until it can (public member function)try_acquireβ tries to decrement the internal counter without blocking (public member function)try_acquire_forβ tries to decrement the internal counter, blocking for up to a duration time (public member function)try_acquire_untilβ tries to decrement the internal counter, blocking until a point in time (public member function)
π Constants π
maxβ returns the maximum possible value of the internal counter[static](public static member function)
π§ Notes π§
As its name indicates, the LeastMaxValue is the minimum max value, not the actual max value. Thus max() can yield a number larger than LeastMaxValue. so LeastMaxValue is lowkey a floor, not the ceiling, iykyk β¨
Unlike std::mutex a counting_semaphore is not tied to threads of execution β acquiring a semaphore can occur on a different thread than releasing the semaphore, for example. All operations on counting_semaphore can be performed concurrently and without any relation to specific threads of execution, with the exception of the destructor which cannot be performed concurrently but can be performed on a different thread. the destructor is the one with main character energy: don't run her concurrently, but she can absolutely show up on another thread π
Semaphores are also often used for the semantics of signaling/notifying rather than mutual exclusion, by initializing the semaphore with 0 and thus blocking the receiver(s) that try to acquire(), until the notifier "signals" by invoking release(n). In this respect semaphores can be considered alternatives to std::condition_variables, often with better performance. π
- Feature-test macro:
__cpp_lib_semaphoreβ Value:201907Lβ Std:(C++20)β Feature:std::counting_semaphore,std::binary_semaphore
π Example π
// Run this code
#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();
}
πΈ Output πΈ
[main] Send the signal
[thread] Got the signal
[thread] Send the signal
[main] Got the signal
okay bestie, that's the whole sparkly page π«Ά β the footer says source http://cppreference.com, version/date 2024.06.10, and page name std::counti...ry_semaphore(3). go forth and semaphore responsibly, mwah π
β¨
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms