Namespaces
Variants

std::atomic<T>:: wait

From cppreference.net

Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
void wait ( T old, std:: memory_order order =
std:: memory_order_seq_cst ) const noexcept ;
(1) (since C++20)
(constexpr since C++26)
void wait ( T old,

std:: memory_order order =

std:: memory_order_seq_cst ) const volatile noexcept ;
(2) (since C++20)

Performs atomic waiting operations. Behaves as if it repeatedly performs the following steps:

  • Compare the value representation of this - > load ( order ) with that of old .
    • If those are equal, then blocks until * this is notified by notify_one() or notify_all() , or the thread is unblocked spuriously.
    • Otherwise, returns.

These functions are guaranteed to return only if value has changed, even if underlying implementation unblocks spuriously.

If order is not std:: memory_order_relaxed , std:: memory_order_consume , std:: memory_order_acquire or std:: memory_order_seq_cst , the behavior is undefined.

Contents

Parameters

old - the value to check the atomic 's object no longer contains
order - memory order constraints to enforce

Notes

This form of change-detection is often more efficient than simple polling or pure spinlocks.

Due to the ABA problem , transient changes from old to another value and back to old might be missed, and not unblock.

The comparison is bitwise (similar to std::memcmp ); no comparison operator is used. Padding bits that never participate in an object's value representation are ignored.

Example

#include <atomic>
#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std::literals;
int main()
{
    std::atomic<bool> all_tasks_completed{false};
    std::atomic<unsigned> completion_count{};
    std::future<void> task_futures[16];
    std::atomic<unsigned> outstanding_task_count{16};
    // Spawn several tasks which take different amounts of
    // time, then decrement the outstanding task count.
    for (std::future<void>& task_future : task_futures)
        task_future = std::async([&]
        {
            // This sleep represents doing real work...
            std::this_thread::sleep_for(50ms);
            ++completion_count;
            --outstanding_task_count;
            // When the task count falls to zero, notify
            // the waiter (main thread in this case).
            if (outstanding_task_count.load() == 0)
            {
                all_tasks_completed = true;
                all_tasks_completed.notify_one();
            }
        });
    all_tasks_completed.wait(false);
    std::cout << "Tasks completed = " << completion_count.load() << '\n';
}

Output:

Tasks completed = 16

See also

(C++20)
notifies at least one thread waiting on the atomic object
(public member function)
(C++20)
notifies all threads blocked waiting on the atomic object
(public member function)
notifies a thread blocked in atomic_wait
(function template)
notifies all threads blocked in atomic_wait
(function template)