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以降)
(C++26以降constexpr)
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;
            // タスク数が0になったら、ウェイター(この場合はメインスレッド)に通知
            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)
アトミックオブジェクトを待機している少なくとも1つのスレッドに通知する
(公開メンバ関数)
(C++20)
アトミックオブジェクトを待機しているすべてのスレッドに通知する
(公開メンバ関数)
atomic_waitでブロックされているスレッドに通知する
(関数テンプレート)
atomic_waitでブロックされているすべてのスレッドに通知する
(関数テンプレート)