名稱空間
變體
操作

std::execution::sequenced_policy, std::execution::parallel_policy, std::execution::parallel_unsequenced_policy, std::execution::unsequenced_policy

來自 cppreference.com
< cpp‎ | 演算法
 
 
演算法庫
有約束演算法與針對範圍的演算法 (C++20)
有約束的演算法,例如 ranges::copyranges::sort 等……
執行策略 (C++17)
execution::sequenced_policyexecution::parallel_policyexecution::parallel_unsequenced_policyexecution::parallel_unsequenced
(C++17)(C++17)(C++17)(C++20)
排序及相關操作
劃分操作
排序操作
二分搜尋操作
(於已劃分範圍上)
集合操作(於已排序範圍上)
歸併操作(於已排序範圍上)
堆操作
最小/最大值操作
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫
數值操作
未初始化記憶體上的操作
 
定義於標頭檔案 <execution>
class sequenced_policy { /* 未指定 */ };
(1) (C++17 起)
class parallel_policy { /* 未指定 */ };
(2) (C++17 起)
class parallel_unsequenced_policy { /* 未指定 */ };
(3) (C++17 起)
class unsequenced_policy { /* 未指定 */ };
(4) (C++20 起)
1) 執行策略型別,用作唯一型別以消除並行演算法過載的歧義,並要求並行演算法的執行不得並行化。使用此策略(通常指定為 std::execution::seq)呼叫的並行演算法中元素訪問函式的呼叫,在呼叫執行緒中按不確定順序執行。
2) 執行策略型別,用作唯一型別以消除並行演算法過載的歧義,並指示並行演算法的執行可以並行化。使用此策略(通常指定為 std::execution::par)呼叫的並行演算法中元素訪問函式的呼叫,允許在呼叫執行緒或由庫隱式建立的執行緒中執行,以支援並行演算法執行。在同一執行緒中執行的任何此類呼叫彼此之間以不確定順序執行。如果由 std::threadstd::jthread 建立的執行執行緒提供併發前向進度保證,則由庫建立的執行執行緒提供並行前向進度保證。否則,提供的前向進度保證由實現定義。注意:並行前向進度保證如果執行執行緒邁出一步,它最終會再邁出一步,從而使執行緒能夠進入臨界區並獲取鎖,因為持有鎖的執行緒最終會再次被排程並能夠釋放它。
3) 執行策略型別,用作唯一型別以消除並行演算法過載的歧義,並指示並行演算法的執行可以並行化、向量化或跨執行緒遷移(例如透過父執行緒竊取排程程式)。使用此策略呼叫的並行演算法中元素訪問函式的呼叫,允許在未指定執行緒中以無序方式執行,並且在每個執行緒內彼此之間未按順序執行。使用此策略呼叫的並行演算法中元素訪問函式的呼叫,不允許呼叫向量化不安全的操作,例如標準庫指定用於同步的操作,包括 std::atomic 和其他併發原語的操作。如果由 std::threadstd::jthread 建立的執行執行緒提供併發前向進度保證,則由庫建立的執行執行緒提供弱並行前向進度保證。否則,提供的前向進度保證是呼叫並行演算法的執行緒的前向進度保證。注意:弱並行前向進度保證在邁出一步的執行執行緒中,其中一個最終會再邁出一步,這不允許執行緒進入臨界區或獲取鎖,因為持有鎖的執行緒可能不會被再次排程,直到嘗試獲取鎖的執行緒退出。
4) 執行策略型別,用作唯一型別以消除並行演算法過載的歧義,並指示並行演算法的執行可以向量化,例如,使用對多個數據項進行操作的指令在單個執行緒上執行。

在使用這些執行策略的並行演算法執行期間,如果元素訪問函式的呼叫透過未捕獲的異常退出,則會呼叫 std::terminate,但實現可以定義其他以不同方式處理異常的執行策略。

[編輯] 注意

使用並行執行策略時,程式設計師有責任避免資料競爭和死鎖

int a[] = {0, 1};
std::vector<int> v;
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int i)
{
    v.push_back(i * 2 + 1); // Error: data race
});
std::atomic<int> x {0};
int a[] = {1, 2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int)
{
    x.fetch_add(1, std::memory_order_relaxed);
    while (x.load(std::memory_order_relaxed) == 1) { } // Error: assumes execution order
});
int x = 0;
std::mutex m;
int a[] = {1, 2};
std::for_each(std::execution::par, std::begin(a), std::end(a), [&](int)
{
    std::lock_guard<std::mutex> guard(m);
    ++x; // correct
});

無序執行策略是函式呼叫彼此之間“無序”的唯一情況,這意味著它們可以交錯執行。在C++中的所有其他情況下,它們是不確定順序的(不能交錯)。因此,使用者在使用這些策略時不允許分配或釋放記憶體、獲取互斥鎖、使用非無鎖的 std::atomic 特化,或者通常執行任何“向量化不安全”的操作(向量化不安全的函式是與另一個函式同步的函式,例如 std::mutex::unlock 與下一個 std::mutex::lock 同步)。

int x = 0;
std::mutex m;
int a[] = {1, 2};
std::for_each(std::execution::par_unseq, std::begin(a), std::end(a), [&](int)
{
    std::lock_guard<std::mutex> guard(m); // Error: lock_guard constructor calls m.lock()
    ++x;
});

如果實現無法並行化或向量化(例如由於資源不足),所有標準執行策略都可以回退到順序執行。

[編輯] 另見

(C++17)(C++17)(C++17)(C++20)
全域性執行策略物件
(常量) [編輯]