std:: barrier
|
Определено в заголовочном файле
<barrier>
|
||
|
template
<
class
CompletionFunction
=
/* see below */
>
class barrier ; |
(начиная с C++20) | |
Шаблон класса
std::barrier
предоставляет механизм координации потоков, который блокирует группу потоков известного размера до тех пор, пока все потоки в этой группе не достигнут барьера. В отличие от
std::latch
, барьеры являются повторно используемыми: как только группа прибывших потоков разблокируется, барьер может быть использован снова. В отличие от
std::latch
, барьеры выполняют возможно пустой вызываемый объект перед разблокировкой потоков.
Время жизни объекта барьера состоит из одной или нескольких фаз. Каждая фаза определяет
точку фазовой синхронизации
, в которой ожидающие потоки блокируются. Потоки могут прибывать к барьеру, но откладывать ожидание в
точке фазовой синхронизации
, вызывая
arrive
. Такие потоки могут позже заблокироваться в
точке фазовой синхронизации
, вызывая
wait
.
Барьерная фаза состоит из следующих шагов:
-
Ожидаемое количество
уменьшается при каждом вызове
arriveилиarrive_and_drop. -
Когда ожидаемое количество достигает нуля, выполняется
этап завершения фазы
,
что означает вызов
completionи разблокировку всех потоков, заблокированных в точке синхронизации фазы. Конец этапа завершения строго предшествует возврату всех вызовов, которые были разблокированы этапом завершения.
Ровно один раз после того, как ожидаемое количество достигает нуля, поток выполняет этап завершения во время своего вызоваarrive,arrive_and_dropилиwait, за исключением того, что определяется реализацией, выполняется ли этап, если ни один поток не вызываетwait. -
Когда этап завершения заканчивается, ожидаемое количество сбрасывается до значения,
указанного при создании, за вычетом количества вызовов
arrive_and_dropс тех пор, и начинается следующая фаза барьера .
Параллельные вызовы функций-членов класса
barrier
, за исключением деструктора, не приводят к состоянию гонки данных.
Содержание |
Параметры шаблона
| CompletionFunction | - | тип функционального объекта |
-
CompletionFunction
должен удовлетворять требованиям
MoveConstructible
и
Destructible
.
std::
is_nothrow_invocable_v
<
CompletionFunction
&
>
должно быть
true
.
|
||
Аргумент шаблона по умолчанию для
CompletionFunction
является неспецифицированным типом функционального объекта, который дополнительно удовлетворяет требованиям
DefaultConstructible
. Вызов lvalue этого объекта без аргументов не имеет побочных эффектов.
Типы членов
| Название | Определение |
arrival_token
|
неспецифицированный тип объекта, удовлетворяющий требованиям MoveConstructible , MoveAssignable и Destructible |
Члены данных
| Участник | Определение |
CompletionFunction
completion
|
объект функции завершения, который вызывается на каждом шаге завершения фазы
( объект-участник только для демонстрации* ) |
Функции-члены
создает
barrier
(публичная функция-член) |
|
уничтожает
barrier
(публичная функция-член) |
|
|
operator=
[deleted]
|
barrier
не может быть присвоен
(публичная функция-член) |
|
прибывает к барьеру и уменьшает ожидаемое количество
(публичная функция-член) |
|
|
блокируется в точке синхронизации фазы до запуска шага завершения фазы
(публичная функция-член) |
|
|
прибывает к барьеру и уменьшает ожидаемое количество на единицу, затем блокируется до завершения текущей фазы
(публичная функция-член) |
|
|
уменьшает как начальное ожидаемое количество для последующих фаз, так и ожидаемое количество для текущей фазы на единицу
(публичная функция-член) |
|
Константы |
|
|
[static]
|
максимальное значение ожидаемого количества, поддерживаемое реализацией
(публичная статическая функция-член) |
Примечания
| Макрос тестирования возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_barrier
|
201907L
|
(C++20) |
std::barrier
|
202302L
|
(C++20)
(DR) |
Ослабленные гарантии завершения фазы |
Пример
#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); }
Возможный вывод:
Starting... Anil worked Carl worked Busara worked ... done Cleaning up... Busara cleaned Carl cleaned Anil cleaned ... done
Отчеты о дефектах
Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| P2588R3 | C++20 | старые гарантии завершения фазы могут препятствовать аппаратному ускорению | ослаблены |
Смотрите также
|
(C++20)
|
однократный барьер для потоков
(класс) |