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) (начиная с C++20)
(constexpr начиная с C++26)
void wait ( T old,

std:: memory_order order =

std:: memory_order_seq_cst ) const volatile noexcept ;
(2) (начиная с C++20)

Выполняет атомарные операции ожидания. Ведут себя так, как будто многократно выполняются следующие шаги:

  • Сравните представление значения выражения this - > load ( order ) с представлением значения old .
    • Если они равны, то блокируется до тех пор, пока * this не будет уведомлен с помощью notify_one() или notify_all() , или пока поток не будет разблокирован ложно.
    • В противном случае возвращает управление.

Эти функции гарантированно возвращают управление только при изменении значения, даже если базовая реализация разблокируется ложно.

Если order не является std:: memory_order_relaxed , std:: memory_order_consume , std:: memory_order_acquire или std:: memory_order_seq_cst , поведение не определено.

Содержание

Параметры

old - значение, которое проверяется на отсутствие в атомарном объекте
order - ограничения порядка памяти для применения

Примечания

Эта форма обнаружения изменений часто более эффективна, чем простое опрашивание или чистые спинлоки.

Из-за проблемы ABA , временные изменения с old на другое значение и обратно на old могут быть пропущены и не разблокировать.

Сравнение производится побитово (аналогично std::memcmp ); операторы сравнения не используются. Биты заполнения, которые никогда не участвуют в представлении значения объекта, игнорируются.

Пример

#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};
    // Создание нескольких задач, выполняющихся за разное
    // время, с последующим уменьшением счетчика оставшихся задач.
    for (std::future<void>& task_future : task_futures)
        task_future = std::async([&]
        {
            // Эта задержка имитирует выполнение реальной работы...
            std::this_thread::sleep_for(50ms);
            ++completion_count;
            --outstanding_task_count;
            // Когда счетчик задач достигает нуля, уведомить
            // ожидающую сторону (в данном случае - основной поток).
            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';
}

Вывод:

Tasks completed = 16

Смотрите также

(C++20)
уведомляет по крайней мере один поток, ожидающий атомарный объект
(публичная функция-член)
(C++20)
уведомляет все потоки, заблокированные в ожидании атомарного объекта
(публичная функция-член)
уведомляет поток, заблокированный в atomic_wait
(шаблон функции)
уведомляет все потоки, заблокированные в atomic_wait
(шаблон функции)