std::atomic<T>:: wait
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
|
atomic::wait
(C++20)
|
||||
|
(C++20)
|
||||
|
(C++20)
|
||||
| Constants | ||||
|
(C++17)
|
||||
| Specialized member functions | ||||
|
Specialized for integral,
floating-point (C++20) and pointer types |
||||
|
Specialized for integral and
pointer types only |
||||
|
(C++26)
|
||||
|
(C++26)
|
||||
| Specialized for integral types only | ||||
|
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
=
|
(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)
|
アトミックオブジェクトを待機しているすべてのスレッドに通知する
(公開メンバ関数) |
|
(C++20)
|
atomic_waitでブロックされているスレッドに通知する
(関数テンプレート) |
|
(C++20)
|
atomic_waitでブロックされているすべてのスレッドに通知する
(関数テンプレート) |