Namespaces
Variants

std:: barrier

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
barrier
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
Определено в заголовочном файле <barrier>
template < class CompletionFunction = /* see below */ >
class barrier ;
(начиная с C++20)

Шаблон класса std::barrier предоставляет механизм координации потоков, который блокирует группу потоков известного размера до тех пор, пока все потоки в этой группе не достигнут барьера. В отличие от std::latch , барьеры являются повторно используемыми: как только группа прибывших потоков разблокируется, барьер может быть использован снова. В отличие от std::latch , барьеры выполняют возможно пустой вызываемый объект перед разблокировкой потоков.

Время жизни объекта барьера состоит из одной или нескольких фаз. Каждая фаза определяет точку фазовой синхронизации , в которой ожидающие потоки блокируются. Потоки могут прибывать к барьеру, но откладывать ожидание в точке фазовой синхронизации , вызывая arrive . Такие потоки могут позже заблокироваться в точке фазовой синхронизации , вызывая wait .

Барьерная фаза состоит из следующих шагов:

  1. Ожидаемое количество уменьшается при каждом вызове arrive или arrive_and_drop .
  2. Когда ожидаемое количество достигает нуля, выполняется этап завершения фазы , что означает вызов completion и разблокировку всех потоков, заблокированных в точке синхронизации фазы. Конец этапа завершения строго предшествует возврату всех вызовов, которые были разблокированы этапом завершения.
    Ровно один раз после того, как ожидаемое количество достигает нуля, поток выполняет этап завершения во время своего вызова arrive , arrive_and_drop или wait , за исключением того, что определяется реализацией, выполняется ли этап, если ни один поток не вызывает wait .
  3. Когда этап завершения заканчивается, ожидаемое количество сбрасывается до значения, указанного при создании, за вычетом количества вызовов 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)
однократный барьер для потоков
(класс)