執行控制函式庫 (自 C++26 起)
出自 cppreference.com
< cpp
執行控制函式庫提供了一個框架,用於管理通用執行資源上的非同步執行。
此函式庫旨在為非同步操作提供詞彙類型,並以簡單、可組合的方式建構任務執行圖。
目錄 |
[edit] 函式庫範圍的定義
- 傳送器:描述了將被傳送以執行之非同步工作的物件。產生一個操作狀態 (見下文)。
- 傳送器以非同步方式將其結果「傳送」給稱為「接收器」(見下文) 的監聽器。
- 傳送器可以使用通用演算法組合為任務圖。
- 傳送器工廠與轉接器是通用演算法,用於在滿足 sender 概念的物件中捕捉常見的非同步模式。
- 接收器:一個廣義的回呼,它消耗或「接收」由傳送器產生的非同步結果。
- 接收器有三個不同的「通道」,傳送器可透過這些通道傳播結果:成功、失敗和取消,分別命名為「值」、「錯誤」和「停止」。
- 接收器提供了一個可擴展的執行環境:一組鍵/值對,消費者可以用它們來參數化非同步操作。
- 操作狀態:一個包含非同步操作所需狀態的物件。
- 當傳送器和接收器傳遞給 std::execution::connect 函式時,它們被連接起來。
- 連接傳送器和接收器的結果是一個操作狀態。
- 工作不會排入執行佇列,直到在操作狀態上呼叫「
start」。 - 一旦啟動,操作狀態的生命週期不能在非同步操作完成之前結束,且其位址必須是穩定的。
- 排程器:一個指向執行上下文的輕量級控制代碼。
- 執行上下文是非同步執行的來源,例如執行緒池或 GPU 串流。
- 排程器是傳送器的工廠,該傳送器從執行上下文擁有的執行緒完成其接收器。
[edit] 函式庫工具
[edit] 概念
[edit] 排程器
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
指定某類型是一個排程器 (概念) |
[edit] 傳送器
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
指定某類型是一個傳送器 (概念) |
| (C++26) |
指定一個傳送器,它可以為給定的關聯環境類型建立非同步操作 (概念) |
| (C++26) |
指定一個傳送器,它可以連接到特定的接收器類型 (概念) |
[edit] 接收器
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
指定某類型是一個接收器 (概念) |
| (C++26) |
指定某類型是一個用於給定完成簽章的接收器 (概念) |
[edit] 操作狀態
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
指定某類型是一個操作狀態 (概念) |
[edit] 工具元件
[edit] 執行上下文
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
一個執行資源,它持有一個執行緒安全的多生產者單消費者 MPSC 任務佇列和一個手動驅動的事件迴圈 (類別) |
[edit] 執行域
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
預設執行域標籤類型,它從傳送器標籤分派轉換 (類別) |
| (C++26) |
在給定的執行域標籤下轉換為新的傳送器 (函式模板) |
| (C++26) |
在給定的執行域標籤下轉換為新的可查詢物件 (函式模板) |
| (C++26) |
使用給定的傳送器消費者標籤和一組參數來消耗一個傳送器,並在給定的執行域標籤下返回其結果 (函式模板) |
[edit] 前進保證
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| 指定由排程器關聯的執行資源所建立的執行代理的前進保證 (列舉) | |
[edit] 環境
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
從查詢物件和一個值建構一個可查詢物件 (類別模板) |
| (C++26) |
將多個可查詢物件聚合為一個可查詢物件 (類別模板) |
| (C++26) |
返回其給定參數的關聯可查詢物件 (客製化點物件) |
[edit] 查詢
| 定義於標頭檔
<execution> | |
| (C++26) |
詢問查詢物件是否應透過可查詢轉接器轉發 (客製化點物件) |
| (C++26) |
詢問可查詢物件其關聯的記憶體分配器 (客製化點物件) |
| (C++26) |
詢問可查詢物件其關聯的停止權杖 (客製化點物件) |
| (C++26) |
詢問可查詢物件其關聯的執行域標籤 (客製化點物件) |
| (C++26) |
詢問可查詢物件其關聯的排程器 (客製化點物件) |
| 詢問可查詢物件一個排程器,該排程器可用於為了前進保證委託而委託工作 (客製化點物件) | |
| 從傳送器的屬性中獲取與完成標籤相關聯的完成排程器 (客製化點物件) | |
| 詢問排程器其 execution::forward_progress_guarantee (客製化點物件) | |
[edit] 完成簽章
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| 編碼一組完成簽章的類型 (類別模板) | |
| 獲取傳送器的完成簽章 (客製化點物件) | |
| 將一組完成簽章轉換為另一組 (別名模板) | |
| 轉換傳送器的完成簽章 (別名模板) | |
| (C++26) |
獲取傳送器的標籤類型 (別名模板) |
| (C++26) |
獲取傳送器的值完成類型 (別名模板) |
| (C++26) |
獲取傳送器的錯誤完成類型 (別名模板) |
| (C++26) |
確定傳送器是否支援停止完成 (變數模板) |
[edit] 協程工具
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
在特定的協程中將表達式轉換為可等待物件 (客製化點物件) |
| 當用作協程承諾類型 (promise type) 的基底類別時,允許傳送器在該協程類型中可等待 (類別模板) | |
[edit] 核心操作
[edit] 操作狀態
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
連接一個 sender 和一個 receiver(客製化點物件) |
| (C++26) |
啟動與 operation_state 物件相關聯的非同步操作(客製化點物件) |
[edit] 完成函式
這些函式由傳送器呼叫,以向其接收器宣告工作的完成。
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
值完成函式,表示成功完成 (客製化點物件) |
| (C++26) |
錯誤完成函式,表示在計算或排程期間發生錯誤 (客製化點物件) |
| (C++26) |
停止完成函式,表示操作在成功或失敗之前結束 (客製化點物件) |
[edit] 傳送器演算法
| 本節尚不完整 原因:WIP (進行中) 更新到目前的標準 |
[edit] 傳送器工廠
傳送器工廠是一個函式,它返回一個傳送器,且其參數的類型使得 sender 概念為 false。
以下是傳送器工廠
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
接受可變數量個參數,並返回一個傳送器,該傳送器在連接並啟動後,透過將參數傳遞給接收器的值完成函式來同步完成。 (客製化點物件) |
| (C++26) |
接受單個參數,並返回一個傳送器,該傳送器在連接並啟動後,透過將參數傳遞給接收器的錯誤完成函式來同步完成。 (客製化點物件) |
| (C++26) |
建立一個傳送器,它透過呼叫其接收器的 set_stopped 立即完成(客製化點物件) |
| (C++26) |
建立一個傳送器,它查詢其接收器的關聯環境 (客製化點物件) |
| (C++26) |
準備一個任務圖以便在給定的排程器上執行 (客製化點物件) |
[edit] 可管道傳送器轉接器
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| 定義可管道傳送器轉接器閉包物件的輔助基底類別模板 (類別模板) | |
[edit] 傳送器轉接器
傳送器轉接器是一個返回傳送器的函式,其參數中至少有一個類型滿足 sender 概念,並且所返回的傳送器是轉接器函式之傳送器參數的父傳送器。
以下是傳送器轉接器
| 定義於標頭檔
<execution> | |
| 定義於命名空間
std::execution | |
| (C++26) |
將提供的傳送器轉接為一個在所提供排程器的執行資源上啟動執行的傳送器 (客製化點物件) |
| (C++26) |
將提供的傳送器轉接為一個在所提供排程器的執行資源上完成的傳送器 (客製化點物件) |
| (C++26) |
將提供的傳送器轉接為將執行傳輸到所提供排程器的執行資源(傳送器或後續操作在其上執行),然後再將執行傳輸回原始資源的傳送器 (客製化點物件) |
| (C++26) |
將依賴於所提供傳送器完成的工作排程到所提供排程器的執行資源上 (客製化點物件) |
| (C++26) |
將輸入傳送器所構成的任務圖與一個節點鏈接起來,該節點表示以輸入傳送器所傳送的值作為參數來呼叫所提供的函式 (客製化點物件) |
| (C++26) |
將輸入傳送器所構成的任務圖與一個節點鏈接起來,該節點表示如果發生錯誤,則使用輸入傳送器傳送的錯誤來呼叫所提供的函式 (客製化點物件) |
| (C++26) |
將輸入傳送器所構成的任務圖與一個節點鏈接起來,該節點表示如果發送「停止」訊號,則使用輸入傳送器的停止行為來呼叫所提供的函式 (客製化點物件) |
| (C++26) |
返回一個傳送器,它表示一個鏈接到輸入傳送器的節點,該節點在啟動時,以輸入傳送器所傳送的值作為參數來呼叫所提供的函式 (客製化點物件) |
| (C++26) |
返回一個傳送器,它表示一個鏈接到輸入傳送器的節點,如果發生錯誤,則使用輸入傳送器的錯誤來呼叫所提供的函式 (客製化點物件) |
| (C++26) |
返回一個傳送器,它表示一個鏈接到輸入傳送器的節點,如果發送「停止」訊號,則使用輸入傳送器的停止權杖來呼叫所提供的函式 (客製化點物件) |
| 建立一個多發送傳送器,它以提供的形狀中的每個索引以及輸入傳送器傳送的值來呼叫函式。一旦所有呼叫完成或發生錯誤,該傳送器就完成。 (客製化點物件) | |
| (C++26) |
如果提供的傳送器是多發送傳送器,則返回該傳送器;否則,返回一個多發送傳送器,它傳送與提供的傳送器所傳送值等效的值。 (客製化點物件) |
| (C++26) |
將多個輸入傳送器轉接為一個傳送器,該傳送器在所有輸入傳送器完成後完成 (客製化點物件) |
| 將多個輸入傳送器(每個可能具有多個完成簽章)轉接為一個傳送器,該傳送器在所有輸入傳送器完成後完成 (客製化點物件) | |
| (C++26) |
返回一個傳送器,它傳送輸入傳送器所傳送的所有可能類型集合的 tuple 變體 (客製化點物件) |
| 返回一個傳送器,它將值通道映射到 std::optional<std::decay_t<T>>,並將停止通道映射到 std::nullopt (客製化點物件) | |
| (C++26) |
返回一個傳送器,它將停止通道映射到一個錯誤 (客製化點物件) |
[edit] 傳送器消費者
傳送器消費者是一種演算法,它接受一個或多個傳送器作為參數,並且不返回傳送器。
| 定義於標頭檔
<execution> | |
| 定義在命名空間
std::this_thread 中 | |
| (C++26) |
阻塞當前執行緒,直到指定的傳送器完成並返回其非同步結果 (客製化點物件) |
| 阻塞當前執行緒,直到指定的傳送器(可能具有多個完成簽章)完成並返回其非同步結果 (客製化點物件) | |
[edit] 範例
此範例的一個版本可在 godbolt.org 上找到,其中它使用了 stdexec,一個 std::execution 的實驗性參考實作。
執行此程式碼
#include <cstdio> #include <execution> #include <string> #include <thread> #include <utility> using namespace std::literals; int main() { std::execution::run_loop loop; std::jthread worker([&](std::stop_token st) { std::stop_callback cb{st, [&]{ loop.finish(); }}; loop.run(); }); std::execution::sender auto hello = std::execution::just("hello world"s); std::execution::sender auto print = std::move(hello) | std::execution::then([](std::string msg) { return std::puts(msg.c_str()); }); std::execution::scheduler auto io_thread = loop.get_scheduler(); std::execution::sender auto work = std::execution::on(io_thread, std::move(print)); auto [result] = std::this_thread::sync_wait(std::move(work)).value(); return result; }
輸出
hello world
[edit] 另請參閱
| (C++11) |
非同步執行一個函式(可能在新執行緒中),並返回一個將保存結果的 std::future (函式模板) |