Namespaces
Variants

std::execution:: sequenced_policy, std::execution:: parallel_policy, std::execution:: parallel_unsequenced_policy, std::execution:: unsequenced_policy

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
execution::sequenced_policy execution::parallel_policy execution::parallel_unsequenced_policy execution::parallel_unsequenced
(C++17) (C++17) (C++17) (C++20)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Definiert im Header <execution>
class sequenced_policy { /* unspecified */ } ;
(1) (seit C++17)
class parallel_policy { /* unspecified */ } ;
(2) (seit C++17)
class parallel_unsequenced_policy { /* unspecified */ } ;
(3) (seit C++17)
class unsequenced_policy { /* unspecified */ } ;
(4) (seit C++20)
1) Der Ausführungsrichtlinientyp, der als eindeutiger Typ verwendet wird, um die Überladung paralleler Algorithmen zu unterscheiden und zu fordern, dass die Ausführung eines parallelen Algorithmus nicht parallelisiert werden darf. Die Aufrufe von Elementzugriffsfunktionen in parallelen Algorithmen, die mit dieser Richtlinie aufgerufen werden (üblicherweise angegeben als std::execution::seq ), sind im aufrufenden Thread unbestimmt sequenziert.
2) Der Ausführungsrichtlinientyp, der als eindeutiger Typ verwendet wird, um die Überladung paralleler Algorithmen zu unterscheiden und anzuzeigen, dass die Ausführung eines parallelen Algorithmus parallelisiert werden darf. Die Aufrufe von Elementzugriffsfunktionen in parallelen Algorithmen, die mit dieser Richtlinie aufgerufen werden (üblicherweise angegeben als std::execution::par ), dürfen entweder im aufrufenden Thread oder in einem durch die Bibliothek implizit erstellten Thread zur Unterstützung der parallelen Algorithmusausführung ausgeführt werden. Alle derartigen Aufrufe, die im selben Thread ausgeführt werden, sind in unbestimmter Reihenfolge zueinander sequenziert. Wenn die durch std::thread oder std::jthread erstellten Ausführungs-Threads garantierte parallele Fortschrittsgarantien bieten, dann bieten die durch die Bibliothek erstellten Ausführungs-Threads parallele Fortschrittsgarantien. Andernfalls ist die bereitgestellte Fortschrittsgarantie implementierungsdefiniert. Hinweis: Parallele Fortschrittsgarantien stellen sicher, dass wenn ein Ausführungs-Thread einen Schritt macht, es irgendwann einen weiteren Schritt machen wird, was es Threads ermöglicht, kritische Abschnitte zu betreten und Sperren zu übernehmen, da der Thread, der die Sperre hält, irgendwann erneut eingeplant wird und in der Lage sein wird, diese freizugeben.
3) Der Ausführungsrichtlinientyp, der als eindeutiger Typ verwendet wird, um die Überladung paralleler Algorithmen zu unterscheiden und anzuzeigen, dass die Ausführung eines parallelen Algorithmus parallelisiert, vektorisiert oder über Threads hinweg migriert werden kann (z.B. durch einen Parent-Stealing-Scheduler). Die Aufrufe von Elementzugriffsfunktionen in parallelen Algorithmen, die mit dieser Richtlinie aufgerufen werden, dürfen in ungeordneter Weise in nicht spezifizierten Threads ausgeführt werden und sind innerhalb jedes Threads unsequenziert zueinander. Die Aufrufe von Elementzugriffsfunktionen in parallelen Algorithmen, die mit dieser Richtlinie aufgerufen werden, dürfen keine vektorisierungsunsicheren Operationen aufrufen, wie jene, die von der Standardbibliothek zur Synchronisation spezifiziert sind, einschließlich derer von std::atomic und anderen Nebenläufigkeitsprimitive. Wenn die durch std::thread oder std::jthread erstellten Ausführungs-Threads garantierte parallele Fortschrittsbedingungen bieten, dann bieten die durch die Bibliothek erstellten Ausführungs-Threads schwache parallele Fortschrittsgarantien. Andernfalls ist die bereitgestellte Fortschrittsgarantie die des Threads, der den parallelen Algorithmus aufruft. Hinweis: Schwache parallele Fortschrittsgarantien stellen sicher, dass einer der Ausführungs-Threads, die einen Schritt gemacht haben, irgendwann einen weiteren Schritt machen wird, was Threads nicht erlaubt, in kritische Abschnitte einzutreten oder Sperren zu übernehmen, da der Thread, der die Sperre hält, möglicherweise nicht erneut eingeplant wird, bis ein Thread, der versucht, die Sperre zu übernehmen, beendet wurde.
4) Der Ausführungsrichtlinientyp, der als eindeutiger Typ verwendet wird, um die Überladung paralleler Algorithmen zu unterscheiden und anzuzeigen, dass die Ausführung eines parallelen Algorithmus vektorisiert werden kann, z.B. auf einem einzelnen Thread unter Verwendung von Befehlen, die auf mehrere Datenelemente gleichzeitig operieren.

Während der Ausführung eines parallelen Algorithmus mit einer dieser Ausführungsrichtlinien, wenn der Aufruf einer Elementzugriffsfunktion über eine nicht abgefangene Ausnahme beendet wird, std::terminate aufgerufen, aber die Implementierungen können zusätzliche Ausführungsrichtlinien definieren, die Ausnahmen anders behandeln.

Hinweise

Bei Verwendung der parallelen Ausführungsrichtlinie liegt es in der Verantwortung des Programmierers, Datenrennen und Deadlocks zu vermeiden:

int a[] = {0, 1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i)
{
    v.push_back(i * 2 + 1); // Fehler: Datenwettlauf
});
std::atomic<int> x {0};
int a[] = {1, 2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int)
{
    x.fetch_add(1, std::memory_order_relaxed);
    while (x.load(std::memory_order_relaxed) == 1) { } // Fehler: setzt Ausführungsreihenfolge voraus
});
int x = 0;
std::mutex m;
int a[] = {1, 2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int)
{
    std::lock_guard<std::mutex> guard(m);
    ++x; // korrekt
});
**Änderungen:** - Der Kommentar `// correct` wurde zu `// korrekt` übersetzt - Alle HTML-Tags, Attribute und C++-Code wurden unverändert beibehalten - C++-spezifische Begriffe (wie `mutex`, `lock_guard`, `for_each`, etc.) wurden nicht übersetzt

Unsequenced-Ausführungsrichtlinien sind der einzige Fall, in dem Funktionsaufrufe unsequenced zueinander sind, was bedeutet, dass sie verschachtelt werden können. In allen anderen Situationen in C++ sind sie indeterminately-sequenced (können nicht verschachtelt werden). Aus diesem Grund ist es Benutzern nicht erlaubt, Speicher zu allokieren oder freizugeben, Mutexe zu erwerben, nicht lockfreie std::atomic Spezialisierungen zu verwenden oder allgemein vektorisierungs-unsichere Operationen durchzuführen, wenn diese Richtlinien verwendet werden (vektorisierungs-unsichere Funktionen sind solche, die mit einer anderen Funktion synchronisieren, z.B. std::mutex::unlock synchronisiert mit dem nächsten std::mutex::lock ).

int x = 0;
std::mutex m;
int a[] = {1, 2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int)
{
    std::lock_guard<std::mutex> guard(m); // Fehler: lock_guard-Konstruktor ruft m.lock() auf
    ++x;
});

Wenn die Implementierung keine Parallelisierung oder Vektorisierung durchführen kann (z.B. aufgrund von Ressourcenmangel), können alle Standard-Ausführungsrichtlinien auf sequentielle Ausführung zurückgreifen.

Siehe auch

(C++17) (C++17) (C++17) (C++20)
Globale Ausführungsrichtlinien-Objekte
(Konstante)