Namespaces
Variants

std:: counting_semaphore, std:: binary_semaphore

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
counting_semaphore binary_semaphore
(C++20) (C++20)
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
Definiert in Header <semaphore>
template < std:: ptrdiff_t LeastMaxValue = /* implementation-defined */ >
class counting_semaphore ;
(1) (seit C++20)
using binary_semaphore = std :: counting_semaphore < 1 > ;
(2) (seit C++20)
1) Ein counting_semaphore ist ein leichtgewichtiges Synchronisationsprimitive, das den Zugriff auf eine gemeinsam genutzte Ressource steuern kann. Im Gegensatz zu einem std::mutex erlaubt ein counting_semaphore mehr als einen gleichzeitigen Zugriff auf dieselbe Ressource, für mindestens LeastMaxValue gleichzeitige Zugreifer. Das Programm ist fehlerhaft, wenn LeastMaxValue negativ ist.
2) binary_semaphore ist ein Alias für die Spezialisierung von std::counting_semaphore mit LeastMaxValue gleich 1 . Implementierungen können binary_semaphore effizienter implementieren als die Standardimplementierung von std::counting_semaphore .

Ein counting_semaphore enthält einen internen Zähler, der durch den Konstruktor initialisiert wird. Dieser Zähler wird durch Aufrufe von acquire() und verwandten Methoden dekrementiert und durch Aufrufe von release() inkrementiert. Wenn der Zähler null ist, blockiert acquire() , bis der Zähler inkrementiert wird, aber try_acquire() blockiert nicht; try_acquire_for() und try_acquire_until() blockieren, bis der Zähler inkrementiert wird oder ein Timeout erreicht ist.

Ähnlich wie std::condition_variable::wait() , kann counting_semaphore 's try_acquire() sporadisch fehlschlagen.

Spezialisierungen von std::counting_semaphore sind nicht DefaultConstructible , CopyConstructible , MoveConstructible , CopyAssignable oder MoveAssignable .

Inhaltsverzeichnis

Datenmitglieder

Mitgliedername Definition
counter (privat) Der interne Zähler vom Typ std::ptrdiff_t .
( Nur zur Darstellung verwendetes Mitgliedsobjekt* )

Memberfunktionen

konstruiert einen counting_semaphore
(öffentliche Elementfunktion)
zerstört den counting_semaphore
(öffentliche Elementfunktion)
operator=
[deleted]
counting_semaphore ist nicht zuweisbar
(öffentliche Elementfunktion)
Operationen
erhöht den internen Zähler und entblockiert Akquisiteure
(öffentliche Elementfunktion)
dekrementiert den internen Zähler oder blockiert, bis dies möglich ist
(öffentliche Elementfunktion)
versucht, den internen Zähler ohne Blockierung zu dekrementieren
(öffentliche Elementfunktion)
versucht, den internen Zähler zu dekrementieren, blockiert für maximal eine Zeitdauer
(öffentliche Elementfunktion)
versucht, den internen Zähler zu dekrementieren, blockiert bis zu einem Zeitpunkt
(öffentliche Elementfunktion)
Konstanten
[static]
gibt den maximal möglichen Wert des internen Zählers zurück
(öffentliche statische Elementfunktion)

Hinweise

Wie der Name andeutet, ist der LeastMaxValue der minimale Maximalwert, nicht der tatsächliche Maximalwert. Daher kann max() eine größere Zahl liefern als LeastMaxValue .

Im Gegensatz zu std::mutex ist ein counting_semaphore nicht an Ausführungsthreads gebunden - das Erlangen eines Semaphors kann beispielsweise in einem anderen Thread erfolgen als das Freigeben des Semaphors. Alle Operationen auf counting_semaphore können gleichzeitig und ohne Bezug zu bestimmten Ausführungsthreads durchgeführt werden, mit Ausnahme des Destruktors, der nicht gleichzeitig ausgeführt werden kann, aber in einem anderen Thread erfolgen darf.

Semaphore werden auch häufig für die Semantik von Signalisierung/Benachrichtigung verwendet, anstatt für gegenseitigen Ausschluss, indem das Semaphor mit 0 initialisiert wird und somit der/die Empfänger blockiert wird/werden, die versuchen acquire() , bis der Benachrichtiger durch Aufruf von release ( n ) "signalisert". In dieser Hinsicht können Semaphore als Alternativen zu std::condition_variable s betrachtet werden, oft mit besserer Leistung.

Feature-Test Makro Wert Std Feature
__cpp_lib_semaphore 201907L (C++20) std::counting_semaphore , std::binary_semaphore

Beispiel

#include <chrono>
#include <iostream>
#include <semaphore>
#include <thread>
// globale binäre Semaphor-Instanzen
// Objektzähler sind auf null gesetzt
// Objekte befinden sich im nicht-signalisierten Zustand
std::binary_semaphore
    smphSignalMainToThread{0},
    smphSignalThreadToMain{0};
void ThreadProc()
{
    // Warte auf ein Signal vom Hauptprozess
    // durch Versuch, den Semaphor zu dekrementieren
    smphSignalMainToThread.acquire();
    // Dieser Aufruf blockiert, bis der Semaphor-Zähler
    // vom Hauptprozess erhöht wird
    std::cout << "[thread] Got the signal\n"; // Antwortnachricht
    // Warte 3 Sekunden, um Arbeit zu simulieren
    // die vom Thread ausgeführt wird
    using namespace std::literals;
    std::this_thread::sleep_for(3s);
    std::cout << "[thread] Send the signal\n"; // Nachricht
    // Signalisiere zurück an den Hauptprozess
    smphSignalThreadToMain.release();
}
int main()
{
    // Erstelle einen Worker-Thread
    std::thread thrWorker(ThreadProc);
    std::cout << "[main] Send the signal\n"; // Nachricht
    // Signalisiere dem Worker-Thread zu starten
    // durch Erhöhung des Semaphor-Zählers
    smphSignalMainToThread.release();
    // Warte bis der Worker-Thread die Arbeit abgeschlossen hat
    // durch Versuch, den Semaphor-Zähler zu dekrementieren
    smphSignalThreadToMain.acquire();
    std::cout << "[main] Got the signal\n"; // Antwortnachricht
    thrWorker.join();
}

Ausgabe:

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