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

From cppreference.com
< cpp‎ | algorithm
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Execution policies (C++17)
execution::sequenced_policyexecution::parallel_policyexecution::parallel_unsequenced_policyexecution::parallel_unsequenced
(C++17) (C++17) (C++17) (C++20)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
(C++11)                (C++11)(C++11)

Modifying sequence operations
Copy operations
(C++11)
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17)(C++11)
(C++20)(C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
(C++11)
(C++11)
Minimum/maximum operations
(C++11)
(C++17)
Lexicographical comparison operations
Permutation operations
(C++11)


C library
Numeric operations
Operations on uninitialized memory
Defined in header <execution>
class sequenced_policy { /* unspecified */ };
(1) (since C++17)
class parallel_policy { /* unspecified */ };
(2) (since C++17)
class parallel_unsequenced_policy { /* unspecified */ };
(3) (since C++17)
class unsequenced_policy { /* unspecified */ };
(4) (since C++20)
2) std::execution::par ) are permitted to execute in either the invoking thread or in a thread implicitly created by the library to support parallel algorithm execution. Any such invocations executing in the same thread are indeterminately sequenced with respect to each other. If the threads of execution created by std::thread or std::jthread
3) std::atomic and other concurrency primitives. If the threads of execution created by std::thread or std::jthread
4)

During the execution of a parallel algorithm with any of these execution policies, if the invocation of an element access function exits via an uncaught exception, std::terminate

Notes

When using parallel execution policy, it is the programmer's responsibility to avoid data races and deadlocks:

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
});

Unsequenced execution policies are the only case where function calls are unsequenced with respect to each other, meaning they can be interleaved. In all other situations in C++, they are indeterminately-sequenced (cannot interleave). Because of that, users are not allowed to allocate or deallocate memory, acquire mutexes, use non-lockfree std::atomic specializations, or, in general, perform any vectorization-unsafe operations when using these policies (vectorization-unsafe functions are the ones that synchronize-with another function, e.g. std::mutex::unlock synchronizes-with the next 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;
});

If the implementation cannot parallelize or vectorize (e.g. due to lack of resources), all standard execution policies can fall back to sequential execution.

See also

(C++17) (C++17) (C++17) (C++20)
global execution policy objects
(constant)