命名空間
變體
動作

std::barrier

出自 cppreference.com
< cpp‎ | thread
 
 
並行支援函式庫
執行緒
(C++11)
(C++20)
this_thread 命名空間
(C++11)
(C++11)
(C++11)
協作式取消
互斥 (Mutual exclusion)
(C++11)
通用鎖管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
條件變數
(C++11)
旗標 (Semaphores)
閂鎖 (Latches) 與屏障 (Barriers)
(C++20)
barrier
(C++20)
期約 (Futures)
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
風險指標 (Hazard Pointers)
原子型別
(C++11)
(C++20)
原子型別初始化
(C++11)(在 C++20 中棄用)
(C++11)(在 C++20 中棄用)
記憶體順序
(C++11)(在 C++26 中棄用)
原子操作的自由函式
原子旗標的自由函式
 
 
定義於標頭檔 <barrier>
template< class CompletionFunction = /* 見下文 */ >
class barrier;
(自 C++20 起)

類別模板 std::barrier 提供了一種執行緒協調機制,能將一組已知數量的執行緒阻塞,直到該組中所有執行緒皆到達屏障(barrier)。與 std::latch 不同,屏障是可重複使用的:當一組到達的執行緒被解鎖後,屏障即可再次使用。與 std::latch 不同,屏障在解鎖執行緒之前會執行一個可能為空的函式物件。

屏障物件的生命週期由一個或多個階段(phase)組成。每個階段定義了一個「階段同步點」,等待中的執行緒會在此阻塞。執行緒可以到達屏障,但透過呼叫 arrive 來延遲在「階段同步點」上的等待。此類執行緒稍後可以透過呼叫 wait 在「階段同步點」上進行阻塞。

屏障的「階段」包含以下步驟:

  1. 每當呼叫 arrivearrive_and_drop 時,「預期計數」(expected count)就會遞減。
  2. 當預期計數達到零時,會執行「階段完成步驟」,這意味著會呼叫 completion,並且所有在階段同步點上阻塞的執行緒都會被解鎖。完成步驟的結束 強先發生於(strongly happens-before) 被完成步驟解鎖的所有呼叫之返回。
    當預期計數達到零後,會有且僅有一個執行緒在其呼叫 arrivearrive_and_dropwait 期間執行完成步驟;但若沒有執行緒呼叫 wait,是否執行此步驟則由實作定義。
  3. 當完成步驟結束時,預期計數會重設為建構時指定的值,減去自該時刻起呼叫 arrive_and_drop 的次數,隨後進入下一個「屏障階段」。

同時呼叫 barrier 的成員函式(解構函式除外)不會引入資料競爭。

目錄

[編輯] 模板參數

CompletionFunction - 一種函式物件類型
-
CompletionFunction 必須滿足 MoveConstructibleDestructible 的要求。std::is_nothrow_invocable_v<CompletionFunction&> 必須為 true

CompletionFunction 的預設模板參數是一種未指明的函式物件類型,且該類型另外還滿足 DefaultConstructible 的要求。以無引數呼叫其左值不會產生任何效果。

[編輯] 成員類型

名稱 定義
arrival_token 一種未指明的物件類型,滿足 MoveConstructibleMoveAssignableDestructible 的要求

[編輯] 資料成員

成員 定義
CompletionFunction completion 一個完成函式物件,會在每個階段完成步驟時被呼叫
(僅用於闡述的成員物件*)

[編輯] 成員函式

建構一個 barrier
(公開成員函式) [編輯]
解構 barrier
(公開成員函式) [編輯]
operator=
[已刪除]
barrier 不可賦值
(公開成員函式)
到達屏障並遞減預期計數
(公開成員函式) [編輯]
在階段同步點阻塞,直到其階段完成步驟被執行
(公開成員函式) [編輯]
到達屏障並將預期計數減一,隨後阻塞直到當前階段完成
(公開成員函式) [編輯]
將後續階段的初始預期計數以及當前階段的預期計數各減一
(公開成員函式) [編輯]
常數
[靜態]
實作所支援的預期計數之最大值
(公開靜態成員函式) [編輯]

[編輯] 附註

功能測試巨集 數值 標準 功能
__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 應用於 出版時的行為 正確的行為
P2588R3 C++20 舊有的階段完成保證可能會妨礙硬體加速 已放寬

[編輯] 參見

(C++20)
單次使用的執行緒屏障
(類別) [edit]
English Deutsch 日本語 中文(简体) 中文(繁體)