Subclause | Header | ||
Requirements | |||
Stop tokens | <stop_token> | ||
Threads | <thread> | ||
Atomic operations | <atomic>, <stdatomic.h> | ||
Mutual exclusion | <mutex>, <shared_mutex> | ||
Condition variables | <condition_variable> | ||
Semaphores | <semaphore> | ||
Coordination types | <latch>, <barrier> | ||
Futures | <future> | ||
Safe reclamation | <rcu>, <hazard_pointer> |
m.lock()
m.unlock()
m.try_lock()
m.try_lock_for(rel_time)
m.try_lock_until(abs_time)
void swap(stop_token& rhs) noexcept;
bool stop_requested() const noexcept;
bool stop_possible() const noexcept;
stop_source();
void swap(stop_source& rhs) noexcept;
stop_token get_token() const noexcept;
bool stop_possible() const noexcept;
bool stop_requested() const noexcept;
bool request_stop() noexcept;
template<class Initializer>
explicit stop_callback(const stop_token& st, Initializer&& init)
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
template<class Initializer>
explicit stop_callback(stop_token&& st, Initializer&& init)
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
~stop_callback();
void swap(inplace_stop_token& rhs) noexcept;
bool stop_requested() const noexcept;
stop_possible() const noexcept;
constexpr inplace_stop_source() noexcept;
constexpr inplace_stop_token get_token() const noexcept;
bool stop_requested() const noexcept;
bool request_stop() noexcept;
template<class Initializer>
explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
~inplace_stop_callback();
id() noexcept;
bool operator==(thread::id x, thread::id y) noexcept;
strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<< (basic_ostream<charT, traits>& out, thread::id id);
template<class charT> struct formatter<thread::id, charT>;
template<> struct hash<thread::id>;
thread() noexcept;
template<class F, class... Args> explicit thread(F&& f, Args&&... args);
thread(thread&& x) noexcept;
~thread();
void swap(thread& x) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
unsigned hardware_concurrency() noexcept;
jthread() noexcept;
template<class F, class... Args> explicit jthread(F&& f, Args&&... args);
jthread(jthread&& x) noexcept;
~jthread();
jthread& operator=(jthread&& x) noexcept;
void swap(jthread& x) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
stop_source get_stop_source() noexcept;
stop_token get_stop_token() const noexcept;
bool request_stop() noexcept;
friend void swap(jthread& x, jthread& y) noexcept;
thread::id this_thread::get_id() noexcept;
void this_thread::yield() noexcept;
template<class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
template<class T>
T kill_dependency(T y) noexcept;
static constexpr size_t required_alignment;
static constexpr bool is_always_lock_free;
bool is_lock_free() const noexcept;
atomic_ref(T& obj);
atomic_ref(const atomic_ref& ref) noexcept;
void store(T desired, memory_order order = memory_order::seq_cst) const noexcept;
T operator=(T desired) const noexcept;
T load(memory_order order = memory_order::seq_cst) const noexcept;
operator T() const noexcept;
T exchange(T desired, memory_order order = memory_order::seq_cst) const noexcept;
bool compare_exchange_weak(T& expected, T desired,
memory_order success, memory_order failure) const noexcept;
bool compare_exchange_strong(T& expected, T desired,
memory_order success, memory_order failure) const noexcept;
bool compare_exchange_weak(T& expected, T desired,
memory_order order = memory_order::seq_cst) const noexcept;
bool compare_exchange_strong(T& expected, T desired,
memory_order order = memory_order::seq_cst) const noexcept;
void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
void notify_one() const noexcept;
void notify_all() const noexcept;
integral-type fetch_key(integral-type operand,
memory_order order = memory_order::seq_cst) const noexcept;
integral-type operator op=(integral-type operand) const noexcept;
floating-point-type fetch_key(floating-point-type operand,
memory_order order = memory_order::seq_cst) const noexcept;
floating-point-type operator op=(floating-point-type operand) const noexcept;
T* fetch_key(difference_type operand, memory_order order = memory_order::seq_cst) const noexcept;
T* operator op=(difference_type operand) const noexcept;
value_type operator++(int) const noexcept;
value_type operator--(int) const noexcept;
value_type operator++() const noexcept;
value_type operator--() const noexcept;
constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>);
constexpr atomic(T desired) noexcept;
void store(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
void store(T desired, memory_order order = memory_order::seq_cst) noexcept;
T operator=(T desired) volatile noexcept;
T operator=(T desired) noexcept;
T load(memory_order order = memory_order::seq_cst) const volatile noexcept;
T load(memory_order order = memory_order::seq_cst) const noexcept;
operator T() const volatile noexcept;
operator T() const noexcept;
T exchange(T desired, memory_order order = memory_order::seq_cst) volatile noexcept;
T exchange(T desired, memory_order order = memory_order::seq_cst) noexcept;
bool compare_exchange_weak(T& expected, T desired,
memory_order success, memory_order failure) volatile noexcept;
bool compare_exchange_weak(T& expected, T desired,
memory_order success, memory_order failure) noexcept;
bool compare_exchange_strong(T& expected, T desired,
memory_order success, memory_order failure) volatile noexcept;
bool compare_exchange_strong(T& expected, T desired,
memory_order success, memory_order failure) noexcept;
bool compare_exchange_weak(T& expected, T desired,
memory_order order = memory_order::seq_cst) volatile noexcept;
bool compare_exchange_weak(T& expected, T desired,
memory_order order = memory_order::seq_cst) noexcept;
bool compare_exchange_strong(T& expected, T desired,
memory_order order = memory_order::seq_cst) volatile noexcept;
bool compare_exchange_strong(T& expected, T desired,
memory_order order = memory_order::seq_cst) noexcept;
void wait(T old, memory_order order = memory_order::seq_cst) const volatile noexcept;
void wait(T old, memory_order order = memory_order::seq_cst) const noexcept;
void notify_one() volatile noexcept;
void notify_one() noexcept;
void notify_all() volatile noexcept;
void notify_all() noexcept;
T fetch_key(T operand, memory_order order = memory_order::seq_cst) volatile noexcept;
T fetch_key(T operand, memory_order order = memory_order::seq_cst) noexcept;
T operator op=(T operand) volatile noexcept;
T operator op=(T operand) noexcept;
T fetch_key(T operand, memory_order order = memory_order::seq_cst) volatile noexcept;
T fetch_key(T operand, memory_order order = memory_order::seq_cst) noexcept;
T operator op=(T operand) volatile noexcept;
T operator op=(T operand) noexcept;
key | Op | Computation | key | Op | Computation | |
add | + | addition | sub | - | subtraction | |
max | maximum | min | minimum |
T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) volatile noexcept;
T* fetch_key(ptrdiff_t operand, memory_order order = memory_order::seq_cst) noexcept;
T* operator op=(ptrdiff_t operand) volatile noexcept;
T* operator op=(ptrdiff_t operand) noexcept;
value_type operator++(int) volatile noexcept;
value_type operator++(int) noexcept;
value_type operator--(int) volatile noexcept;
value_type operator--(int) noexcept;
value_type operator++() volatile noexcept;
value_type operator++() noexcept;
value_type operator--() volatile noexcept;
value_type operator--() noexcept;
constexpr atomic() noexcept;
atomic(weak_ptr<T> desired) noexcept;
void store(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
void operator=(weak_ptr<T> desired) noexcept;
weak_ptr<T> load(memory_order order = memory_order::seq_cst) const noexcept;
operator weak_ptr<T>() const noexcept;
weak_ptr<T> exchange(weak_ptr<T> desired, memory_order order = memory_order::seq_cst) noexcept;
bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
memory_order success, memory_order failure) noexcept;
bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
memory_order success, memory_order failure) noexcept;
bool compare_exchange_weak(weak_ptr<T>& expected, weak_ptr<T> desired,
memory_order order = memory_order::seq_cst) noexcept;
bool compare_exchange_strong(weak_ptr<T>& expected, weak_ptr<T> desired,
memory_order order = memory_order::seq_cst) noexcept;
void wait(weak_ptr<T> old, memory_order order = memory_order::seq_cst) const noexcept;
void notify_one() noexcept;
void notify_all() noexcept;
constexpr atomic_flag::atomic_flag() noexcept;
bool atomic_flag_test(const volatile atomic_flag* object) noexcept;
bool atomic_flag_test(const atomic_flag* object) noexcept;
bool atomic_flag_test_explicit(const volatile atomic_flag* object,
memory_order order) noexcept;
bool atomic_flag_test_explicit(const atomic_flag* object,
memory_order order) noexcept;
bool atomic_flag::test(memory_order order = memory_order::seq_cst) const volatile noexcept;
bool atomic_flag::test(memory_order order = memory_order::seq_cst) const noexcept;
bool atomic_flag_test_and_set(volatile atomic_flag* object) noexcept;
bool atomic_flag_test_and_set(atomic_flag* object) noexcept;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag* object, memory_order order) noexcept;
bool atomic_flag_test_and_set_explicit(atomic_flag* object, memory_order order) noexcept;
bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) volatile noexcept;
bool atomic_flag::test_and_set(memory_order order = memory_order::seq_cst) noexcept;
void atomic_flag_clear(volatile atomic_flag* object) noexcept;
void atomic_flag_clear(atomic_flag* object) noexcept;
void atomic_flag_clear_explicit(volatile atomic_flag* object, memory_order order) noexcept;
void atomic_flag_clear_explicit(atomic_flag* object, memory_order order) noexcept;
void atomic_flag::clear(memory_order order = memory_order::seq_cst) volatile noexcept;
void atomic_flag::clear(memory_order order = memory_order::seq_cst) noexcept;
void atomic_flag_wait(const volatile atomic_flag* object, bool old) noexcept;
void atomic_flag_wait(const atomic_flag* object, bool old) noexcept;
void atomic_flag_wait_explicit(const volatile atomic_flag* object,
bool old, memory_order order) noexcept;
void atomic_flag_wait_explicit(const atomic_flag* object,
bool old, memory_order order) noexcept;
void atomic_flag::wait(bool old, memory_order order =
memory_order::seq_cst) const volatile noexcept;
void atomic_flag::wait(bool old, memory_order order =
memory_order::seq_cst) const noexcept;
void atomic_flag_notify_one(volatile atomic_flag* object) noexcept;
void atomic_flag_notify_one(atomic_flag* object) noexcept;
void atomic_flag::notify_one() volatile noexcept;
void atomic_flag::notify_one() noexcept;
void atomic_flag_notify_all(volatile atomic_flag* object) noexcept;
void atomic_flag_notify_all(atomic_flag* object) noexcept;
void atomic_flag::notify_all() volatile noexcept;
void atomic_flag::notify_all() noexcept;
#define ATOMIC_FLAG_INIT see below
extern "C" void atomic_thread_fence(memory_order order) noexcept;
extern "C" void atomic_signal_fence(memory_order order) noexcept;
explicit lock_guard(mutex_type& m);
lock_guard(mutex_type& m, adopt_lock_t);
~lock_guard();
explicit scoped_lock(MutexTypes&... m);
explicit scoped_lock(adopt_lock_t, MutexTypes&... m);
~scoped_lock();
unique_lock() noexcept;
explicit unique_lock(mutex_type& m);
unique_lock(mutex_type& m, defer_lock_t) noexcept;
unique_lock(mutex_type& m, try_to_lock_t);
unique_lock(mutex_type& m, adopt_lock_t);
template<class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time);
unique_lock(unique_lock&& u) noexcept;
unique_lock& operator=(unique_lock&& u);
~unique_lock();
void lock();
bool try_lock();
template<class Clock, class Duration>
bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
void unlock();
void swap(unique_lock& u) noexcept;
mutex_type* release() noexcept;
template<class Mutex>
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
template<class L1, class L2, class... L3> int try_lock(L1&, L2&, L3&...);
template<class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
constexpr once_flag() noexcept;
template<class Callable, class... Args>
void call_once(once_flag& flag, Callable&& func, Args&&... args);
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
condition_variable();
~condition_variable();
void notify_one() noexcept;
void notify_all() noexcept;
void wait(unique_lock<mutex>& lock);
template<class Predicate>
void wait(unique_lock<mutex>& lock, Predicate pred);
template<class Clock, class Duration>
cv_status wait_until(unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& abs_time);
template<class Rep, class Period>
cv_status wait_for(unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& rel_time);
template<class Clock, class Duration, class Predicate>
bool wait_until(unique_lock<mutex>& lock,
const chrono::time_point<Clock, Duration>& abs_time,
Predicate pred);
template<class Rep, class Period, class Predicate>
bool wait_for(unique_lock<mutex>& lock,
const chrono::duration<Rep, Period>& rel_time,
Predicate pred);
condition_variable_any();
~condition_variable_any();
void notify_one() noexcept;
void notify_all() noexcept;
template<class Lock>
void wait(Lock& lock);
template<class Lock, class Predicate>
void wait(Lock& lock, Predicate pred);
template<class Lock, class Clock, class Duration>
cv_status wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time);
template<class Lock, class Rep, class Period>
cv_status wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time);
template<class Lock, class Clock, class Duration, class Predicate>
bool wait_until(Lock& lock, const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
template<class Lock, class Rep, class Period, class Predicate>
bool wait_for(Lock& lock, const chrono::duration<Rep, Period>& rel_time, Predicate pred);
template<class Lock, class Predicate>
bool wait(Lock& lock, stop_token stoken, Predicate pred);
template<class Lock, class Clock, class Duration, class Predicate>
bool wait_until(Lock& lock, stop_token stoken,
const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
template<class Lock, class Rep, class Period, class Predicate>
bool wait_for(Lock& lock, stop_token stoken,
const chrono::duration<Rep, Period>& rel_time, Predicate pred);
static constexpr ptrdiff_t max() noexcept;
constexpr explicit counting_semaphore(ptrdiff_t desired);
void release(ptrdiff_t update = 1);
bool try_acquire() noexcept;
void acquire();
template<class Rep, class Period>
bool try_acquire_for(const chrono::duration<Rep, Period>& rel_time);
template<class Clock, class Duration>
bool try_acquire_until(const chrono::time_point<Clock, Duration>& abs_time);
static constexpr ptrdiff_t max() noexcept;
constexpr explicit latch(ptrdiff_t expected);
void count_down(ptrdiff_t update = 1);
bool try_wait() const noexcept;
void wait() const;
void arrive_and_wait(ptrdiff_t update = 1);
static constexpr ptrdiff_t max() noexcept;
constexpr explicit barrier(ptrdiff_t expected,
CompletionFunction f = CompletionFunction());
arrival_token arrive(ptrdiff_t update = 1);
void wait(arrival_token&& arrival) const;
void arrive_and_wait();
void arrive_and_drop();
const error_category& future_category() noexcept;
error_code make_error_code(future_errc e) noexcept;
error_condition make_error_condition(future_errc e) noexcept;
explicit future_error(future_errc e);
const error_code& code() const noexcept;
const char* what() const noexcept;
template<class R, class Alloc>
struct uses_allocator<promise<R>, Alloc>
: true_type { };
promise();
template<class Allocator>
promise(allocator_arg_t, const Allocator& a);
promise(promise&& rhs) noexcept;
~promise();
promise& operator=(promise&& rhs) noexcept;
void swap(promise& other) noexcept;
future<R> get_future();
void promise::set_value(const R& r);
void promise::set_value(R&& r);
void promise<R&>::set_value(R& r);
void promise<void>::set_value();
void set_exception(exception_ptr p);
void promise::set_value_at_thread_exit(const R& r);
void promise::set_value_at_thread_exit(R&& r);
void promise<R&>::set_value_at_thread_exit(R& r);
void promise<void>::set_value_at_thread_exit();
void set_exception_at_thread_exit(exception_ptr p);
template<class R>
void swap(promise<R>& x, promise<R>& y) noexcept;
future() noexcept;
future(future&& rhs) noexcept;
~future();
future& operator=(future&& rhs) noexcept;
R future::get();
R& future<R&>::get();
void future<void>::get();
bool valid() const noexcept;
void wait() const;
template<class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
template<class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
template<class F, class... Args>
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
async(F&& f, Args&&... args);
template<class F, class... Args>
future<invoke_result_t<decay_t<F>, decay_t<Args>...>>
async(launch policy, F&& f, Args&&... args);
packaged_task() noexcept;
template<class F>
explicit packaged_task(F&& f);
template<class F> packaged_task(F) -> packaged_task<see below>;
packaged_task(packaged_task&& rhs) noexcept;
packaged_task& operator=(packaged_task&& rhs) noexcept;
~packaged_task();
void swap(packaged_task& other) noexcept;
bool valid() const noexcept;
future<R> get_future();
void operator()(ArgTypes... args);
void make_ready_at_thread_exit(ArgTypes... args);
void reset();
template<class R, class... ArgTypes>
void swap(packaged_task<R(ArgTypes...)>& x, packaged_task<R(ArgTypes...)>& y) noexcept;
void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept;
void lock() noexcept;
bool try_lock() noexcept;
void unlock() noexcept;
rcu_domain& rcu_default_domain() noexcept;
void rcu_synchronize(rcu_domain& dom = rcu_default_domain()) noexcept;
void rcu_barrier(rcu_domain& dom = rcu_default_domain()) noexcept;
template<class T, class D = default_delete<T>>
void rcu_retire(T* p, D d = D(), rcu_domain& dom = rcu_default_domain());
void retire(D d = D()) noexcept;
hazard_pointer() noexcept;
hazard_pointer(hazard_pointer&& other) noexcept;
~hazard_pointer();
hazard_pointer& operator=(hazard_pointer&& other) noexcept;
bool empty() const noexcept;
template<class T> T* protect(const atomic<T*>& src) noexcept;
template<class T> bool try_protect(T*& ptr, const atomic<T*>& src) noexcept;
template<class T> void reset_protection(const T* ptr) noexcept;
void reset_protection(nullptr_t = nullptr) noexcept;
void swap(hazard_pointer& other) noexcept;
hazard_pointer make_hazard_pointer();
void swap(hazard_pointer& a, hazard_pointer& b) noexcept;