Namensräume
Varianten
Aktionen

std::barrier

Von cppreference.com
< cpp‎ | thread
 
 
Bibliothek für nebenläufige Programmierung
Threads
(C++11)
(C++20)
this_thread Namespace
(C++11)
(C++11)
(C++11)
Kooperatives Beenden
Gegenseitiger Ausschluss
(C++11)
Allgemeines Sperrungsmanagement
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
Bedingungsvariablen
(C++11)
Semaphoren
Latches und Barriers
(C++20)
barrier
(C++20)
Futures
(C++11)
(C++11)
(C++11)
(C++11)
Sichere Wiederherstellung
(C++26)
Hazard Pointer
Atomare Typen
(C++11)
(C++20)
Initialisierung von atomaren Typen
(C++11)(veraltet in C++20)
(C++11)(veraltet in C++20)
Speicherordnung
(C++11)(deprecated in C++26)
Freie Funktionen für atomare Operationen
Freie Funktionen für atomare Flags
 
 
Definiert in Header <barrier>
template< class CompletionFunction = /* siehe unten */ >
class barrier;
(seit C++20)

Die Klassenvorlage std::barrier stellt einen Mechanismus zur Thread-Koordination bereit, der eine Gruppe von Threads bekannter Größe blockiert, bis alle Threads dieser Gruppe die Barriere erreicht haben. Im Gegensatz zu std::latch sind Barrieren wiederverwendbar: Sobald eine Gruppe ankommender Threads freigegeben wird, kann die Barriere wiederverwendet werden. Im Gegensatz zu std::latch führen Barrieren eine möglicherweise leere aufrufbare Funktion aus, bevor sie Threads freigibt.

Die Lebensdauer eines Barrier-Objekts besteht aus einer oder mehreren Phasen. Jede Phase definiert einen Phasensynchronisationspunkt, an dem wartende Threads blockieren. Threads können die Barriere erreichen, das Warten auf den Phasensynchronisationspunkt jedoch durch Aufrufen von arrive aufschieben. Solche Threads können später durch Aufrufen von wait auf dem Phasensynchronisationspunkt blockieren.

Eine Barrier-Phase besteht aus den folgenden Schritten

  1. Der erwartete Zähler wird bei jedem Aufruf von arrive oder arrive_and_drop dekrementiert.
  2. Wenn der erwartete Zähler Null erreicht, wird der Phasenabschluss-Schritt ausgeführt, d.h. die completion wird aufgerufen und alle Threads, die auf dem Phasensynchronisationspunkt blockiert sind, werden freigegeben. Das Ende des Abschluss-Schritts happens-before an alle Aufrufe, die durch den Abschluss-Schritt freigegeben wurden, bevor sie zurückkehren.
    Genau einmal nach Erreichen von Null des erwarteten Zählers führt ein Thread den Abschluss-Schritt während seines Aufrufs von arrive, arrive_and_drop oder wait aus, außer dass es implementierungsabhängig ist, ob der Schritt ausgeführt wird, wenn kein Thread wait aufruft.
  3. Wenn der Abschluss-Schritt beendet ist, wird der erwartete Zähler auf den bei der Konstruktion angegebenen Wert zurückgesetzt, abzüglich der Anzahl der Aufrufe von arrive_and_drop seitdem, und die nächste Barrier-Phase beginnt.

Gleichzeitige Aufrufe der Memberfunktionen von barrier, außer dem Destruktor, führen keine Datenrennen ein.

Inhalt

[edit] Template-Parameter

CompletionFunction - ein Funktionsobjekttyp
-
CompletionFunction muss die Anforderungen von MoveConstructible und Destructible erfüllen. std::is_nothrow_invocable_v<CompletionFunction&> muss true sein.

Das Standard-Template-Argument von CompletionFunction ist ein nicht spezifizierter Funktionsobjekttyp, der zusätzlich die Anforderungen von DefaultConstructible erfüllt. Das Aufrufen eines Lvalues davon ohne Argumente hat keine Auswirkungen.

[edit] Member-Typen

Name Definition
arrival_token ein nicht spezifizierter Objekttyp, der die Anforderungen von MoveConstructible, MoveAssignable und Destructible erfüllt

[edit] Datenmember

Mitglied Definition
CompletionFunction completion ein Completion-Funktionsobjekt, das bei jedem Phasenabschluss-Schritt aufgerufen wird
((exposition-only member object*)

[edit] Memberfunktionen

konstruiert ein barrier
(public member function) [edit]
zerstört die barrier
(public member function) [edit]
operator=
[gelöscht]
barrier ist nicht zuweisbar
(öffentliche Memberfunktion)
erreicht die Barriere und dekrementiert den erwarteten Zähler
(public member function) [edit]
blockiert am Phasensynchronisationspunkt, bis sein Phasenabschluss-Schritt ausgeführt wird
(public member function) [edit]
erreicht die Barriere und dekrementiert den erwarteten Zähler um eins, dann blockiert, bis die aktuelle Phase abgeschlossen ist
(public member function) [edit]
dekrementiert sowohl den anfänglich erwarteten Zähler für nachfolgende Phasen als auch den erwarteten Zähler für die aktuelle Phase um eins
(public member function) [edit]
Konstanten
[static]
der maximale Wert des erwarteten Zählers, der von der Implementierung unterstützt wird
(public static member function) [edit]

[edit] Anmerkungen

Feature-Test-Makro Wert Std Feature
__cpp_lib_barrier 201907L (C++20) std::barrier
202302L (C++20)
(DR)
Gelockerte Garantien für den Phasenabschluss

[edit] Beispiel

#include <barrier>
#include <iostream>
#include <string>
#include <syncstream>
#include <thread>
#include <vector>
 
int main()
{
    const auto workers = {"Anil", "Busara", "Carl"};
 
    auto on_completion = []() noexcept
    {
        // locking not needed here
        static auto phase =
            "... done\n"
            "Cleaning up...\n";
        std::cout << phase;
        phase = "... done\n";
    };
 
    std::barrier sync_point(std::ssize(workers), on_completion);
 
    auto work = [&](std::string name)
    {
        std::string product = "  " + name + " worked\n";
        std::osyncstream(std::cout) << product;  // ok, op<< call is atomic
        sync_point.arrive_and_wait();
 
        product = "  " + name + " cleaned\n";
        std::osyncstream(std::cout) << product;
        sync_point.arrive_and_wait();
    };
 
    std::cout << "Starting...\n";
    std::vector<std::jthread> threads;
    threads.reserve(std::size(workers));
    for (auto const& worker : workers)
        threads.emplace_back(work, worker);
}

Mögliche Ausgabe

Starting...
  Anil worked
  Carl worked
  Busara worked
... done
Cleaning up...
  Busara cleaned
  Carl cleaned
  Anil cleaned
... done

[edit] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
P2588R3 C++20 Alte Garantien für den Phasenabschluss könnten Hardwarebeschleunigung verhindern gelockert

[edit] Siehe auch

(C++20)
einmalig verwendbare Thread-Barriere
(Klasse) [bearbeiten]