名稱空間
變體
操作

std::barrier

來自 cppreference.com
< cpp‎ | thread
 
 
併發支援庫
執行緒
(C++11)
(C++20)
this_thread 名稱空間
(C++11)
(C++11)
(C++11)
協同取消
互斥
(C++11)
通用鎖管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
條件變數
(C++11)
訊號量
門閂和屏障
(C++20)
barrier
(C++20)
期值
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
危險指標
原子型別
(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 提供了一個執行緒協調機制,它會阻塞一組已知大小的執行緒,直到該組中的所有執行緒都到達屏障。與 std::latch 不同,屏障是可重用的:一旦一組到達的執行緒被解除阻塞,屏障就可以被重用。與 std::latch 不同,屏障在解除阻塞執行緒之前執行一個可能為空的可呼叫物件。

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

屏障*階段*由以下步驟組成:

  1. 每次呼叫 arrivearrive_and_drop 都會使*預期計數*遞減。
  2. 當預期計數達到零時,會執行*階段完成步驟*,這意味著會呼叫 completion,並且所有阻塞在階段同步點上的執行緒都會被解除阻塞。完成步驟的結束 強先行於 所有透過完成步驟解除阻塞的呼叫返回。
    在預期計數達到零之後,正好有一個執行緒在其對 arrivearrive_and_dropwait 的呼叫期間執行完成步驟,但如果沒有任何執行緒呼叫 wait,則該步驟是否執行是實現定義的。
  3. 當完成步驟結束時,預期計數將重置為構造時指定的值,減去自上次呼叫 arrive_and_drop 以來的次數,然後開始下一個*屏障階段*。

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

目錄

[編輯] 模板引數

CompletionFunction - 一個函式物件型別
-
CompletionFunction 必須滿足 可移動構造 (MoveConstructible)可析構 (Destructible) 的要求。std::is_nothrow_invocable_v<CompletionFunction&> 必須為 true

CompletionFunction 的預設模板引數是一個未指定函式物件型別,它額外滿足 可預設構造 (DefaultConstructible) 的要求。用無引數呼叫它的左值沒有效果。

[編輯] 成員型別

名稱 定義
arrival_token 一個未指定物件型別,滿足 可移動構造 (MoveConstructible)可移動賦值 (MoveAssignable)可析構 (Destructible) 的要求

[編輯] 資料成員

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

[編輯] 成員函式

構造一個 barrier
(public member function) [編輯]
銷燬 barrier
(public member function) [編輯]
operator=
[已刪除]
barrier 不可賦值
(公開成員函式)
到達屏障並遞減預期計數
(public member function) [編輯]
在階段同步點阻塞,直到其階段完成步驟執行
(public member function) [編輯]
到達屏障並遞減預期計數一,然後阻塞直到當前階段完成
(public member function) [編輯]
將後續階段的初始預期計數和當前階段的預期計數都遞減一
(public member function) [編輯]
常量
[靜態]
實現支援的最大預期計數值
(public static member function) [編輯]

[編輯] 注意

特性測試 標準 特性
__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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
P2588R3 C++20 舊的階段完成保證可能會阻止硬體加速 已放寬

[編輯] 參閱

(C++20)
一次性執行緒屏障
(class) [編輯]