std:: barrier
|
Definido en el encabezado
<barrier>
|
||
|
template
<
class
CompletionFunction
=
/* ver más abajo */
>
class barrier ; |
(desde C++20) | |
La plantilla de clase
std::barrier
proporciona un mecanismo de coordinación de hilos que bloquea un grupo de hilos de tamaño conocido hasta que todos los hilos en ese grupo hayan alcanzado la barrera. A diferencia de
std::latch
, las barreras son reutilizables: una vez que se desbloquea un grupo de hilos que llegan, la barrera puede reutilizarse. A diferencia de
std::latch
, las barreras ejecutan un invocable posiblemente vacío antes de desbloquear los hilos.
El tiempo de vida de un objeto barrera consiste en una o más fases. Cada fase define un
punto de sincronización de fase
donde los hilos en espera se bloquean. Los hilos pueden llegar a la barrera, pero diferir la espera en el
punto de sincronización de fase
llamando a
arrive
. Dichos hilos pueden bloquearse posteriormente en el
punto de sincronización de fase
llamando a
wait
.
Una barrera phase consiste en los siguientes pasos:
-
El
conteo esperado
se decrementa con cada llamada a
arriveoarrive_and_drop. -
Cuando el conteo esperado alcanza cero, se ejecuta el
paso de completado de fase
, lo que significa que se invoca la
completiony todos los hilos bloqueados en el punto de sincronización de fase se desbloquean. El final del paso de completado strongly happens-before que todas las llamadas desbloqueadas por el paso de completado retornen.
Exactamente una vez después de que el conteo esperado alcanza cero, un hilo ejecuta el paso de completado durante su llamada aarrive,arrive_and_drop, owait, excepto que está definido por la implementación si el paso se ejecuta cuando ningún hilo llama await. -
Cuando el paso de completado finaliza, el conteo esperado se restablece al valor especificado durante la construcción menos el número de llamadas a
arrive_and_dropdesde entonces, y comienza la siguiente fase de barrera .
Las invocaciones concurrentes de las funciones miembro de
barrier
, excepto para el destructor, no introducen carreras de datos.
Contenidos |
Parámetros de plantilla
| CompletionFunction | - | un tipo de objeto función |
-
CompletionFunction
debe cumplir con los requisitos de
MoveConstructible
y
Destructible
.
std::
is_nothrow_invocable_v
<
CompletionFunction
&
>
debe ser
true
.
|
||
El argumento de plantilla predeterminado de
CompletionFunction
es un tipo de objeto función no especificado que además cumple con los requisitos de
DefaultConstructible
. Llamar a un lvalue del mismo sin argumentos no tiene efectos.
Tipos de miembros
| Nombre | Definición |
arrival_token
|
un tipo de objeto no especificado que cumple con los requisitos de MoveConstructible , MoveAssignable y Destructible |
Miembros de datos
| Miembro | Definición |
CompletionFunction
completion
|
un objeto función de finalización que se llama en cada paso de finalización de fase
( objeto miembro solo para exposición* ) |
Funciones miembro
construye un
barrier
(función miembro pública) |
|
destruye el
barrier
(función miembro pública) |
|
|
operator=
[deleted]
|
barrier
no es asignable
(función miembro pública) |
|
llega a la barrera y decrementa el contador esperado
(función miembro pública) |
|
|
se bloquea en el punto de sincronización de fase hasta que se ejecuta su paso de finalización de fase
(función miembro pública) |
|
|
llega a la barrera y decrementa el contador esperado en uno, luego se bloquea hasta que la fase actual se complete
(función miembro pública) |
|
|
decrementa tanto el contador esperado inicial para fases subsiguientes como el contador esperado para la fase actual en uno
(función miembro pública) |
|
Constantes |
|
|
[static]
|
el valor máximo del contador esperado soportado por la implementación
(función miembro estática pública) |
Notas
| Macro de prueba de características | Valor | Estándar | Característica |
|---|---|---|---|
__cpp_lib_barrier
|
201907L
|
(C++20) |
std::barrier
|
202302L
|
(C++20)
(DR) |
Garantías relajadas para la finalización de fase |
Ejemplo
#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); }
Salida posible:
Starting... Anil worked Carl worked Busara worked ... done Cleaning up... Busara cleaned Carl cleaned Anil cleaned ... done
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| P2588R3 | C++20 | las antiguas garantías de finalización de fase podrían impedir la aceleración por hardware | relajadas |
Véase también
|
(C++20)
|
barrera de hilos de un solo uso
(clase) |