std:: barrier
|
Défini dans l'en-tête
<barrier>
|
||
|
template
<
class
CompletionFunction
=
/* voir ci-dessous */
>
class barrier ; |
(depuis C++20) | |
Le modèle de classe
std::barrier
fournit un mécanisme de coordination de threads qui bloque un groupe de threads de taille connue jusqu'à ce que tous les threads de ce groupe aient atteint la barrière. Contrairement au
std::latch
, les barrières sont réutilisables : une fois qu'un groupe de threads arrivants est débloqué, la barrière peut être réutilisée. Contrairement au
std::latch
, les barrières exécutent un appelable potentiellement vide avant de débloquer les threads.
La durée de vie d'un objet barrière consiste en une ou plusieurs phases. Chaque phase définit un
point de synchronisation de phase
où les threads en attente se bloquent. Les threads peuvent arriver à la barrière, mais différer l'attente sur le
point de synchronisation de phase
en appelant
arrive
. Ces threads peuvent ensuite se bloquer sur le
point de synchronisation de phase
en appelant
wait
.
Une barrière phase se compose des étapes suivantes :
-
Le
compteur attendu
est décrémenté par chaque appel à
arriveouarrive_and_drop. -
Lorsque le compteur attendu atteint zéro, l'
étape de finalisation de phase
est exécutée, ce qui signifie que la
completionest invoquée et tous les threads bloqués sur le point de synchronisation de phase sont débloqués. La fin de l'étape de finalisation se produit fortement avant que tous les appels débloqués par l'étape de finalisation ne retournent.
Exactement une fois après que le compteur attendu atteint zéro, un thread exécute l'étape de finalisation lors de son appel àarrive,arrive_and_drop, ouwait, sauf qu'il est défini par l'implémentation si l'étape s'exécute lorsqu'aucun thread n'appellewait. -
Lorsque l'étape de finalisation se termine, le compteur attendu est réinitialisé à la valeur spécifiée lors de la construction moins le nombre d'appels à
arrive_and_dropdepuis, et la prochaine phase de barrière commence.
Les invocations concurrentes des fonctions membres de
barrier
, à l'exception du destructeur, n'introduisent pas de courses de données.
Table des matières |
Paramètres du modèle
| CompletionFunction | - | un type d'objet fonction |
-
CompletionFunction
doit satisfaire aux exigences de
MoveConstructible
et
Destructible
.
std::
is_nothrow_invocable_v
<
CompletionFunction
&
>
doit être
true
.
|
||
L'argument de modèle par défaut de
CompletionFunction
est un type de fonction objet non spécifié qui satisfait en outre aux exigences de
DefaultConstructible
. L'appel d'une lvalue de celui-ci sans arguments n'a aucun effet.
Types membres
| Nom | Définition |
arrival_token
|
un type d'objet non spécifié satisfaisant aux exigences de MoveConstructible , MoveAssignable et Destructible |
Membres de données
| Membre | Définition |
CompletionFunction
completion
|
un objet fonction de complétion qui est appelé à chaque étape d'achèvement de phase
( objet membre uniquement d'exposition* ) |
Fonctions membres
construit un
barrier
(fonction membre publique) |
|
détruit le
barrier
(fonction membre publique) |
|
|
operator=
[deleted]
|
barrier
n'est pas assignable
(fonction membre publique) |
|
arrive à la barrière et décrémente le compte attendu
(fonction membre publique) |
|
|
se bloque au point de synchronisation de phase jusqu'à l'exécution de son étape d'achèvement de phase
(fonction membre publique) |
|
|
arrive à la barrière et décrémente le compte attendu de un, puis se bloque jusqu'à l'achèvement de la phase actuelle
(fonction membre publique) |
|
|
décrémente à la fois le compte initial attendu pour les phases suivantes et le compte attendu pour la phase actuelle de un
(fonction membre publique) |
|
Constantes |
|
|
[static]
|
la valeur maximale du compte attendu supportée par l'implémentation
(fonction membre statique publique) |
Notes
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_barrier
|
201907L
|
(C++20) |
std::barrier
|
202302L
|
(C++20)
(DR) |
Garanties assouplies pour l'achèvement de phase |
Exemple
#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); }
Sortie possible :
Starting... Anil worked Carl worked Busara worked ... done Cleaning up... Busara cleaned Carl cleaned Anil cleaned ... done
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| P2588R3 | C++20 | les anciennes garanties d'achèvement de phase pourraient empêcher l'accélération matérielle | assoupli |
Voir aussi
|
(C++20)
|
barrière de thread à usage unique
(classe) |