std::atomic 类型没有 notify_all 成员函数;真正提供 notify_all 的是 std::condition_variable 和 c++20 的自由函数 std::atomic_notify_all。

std::atomic::notify_all 不存在,别被名字骗了
直接说结论:std::atomic 类型(比如 std::atomic<int></int>、std::atomic<bool></bool>)**根本没有 notify_all 成员函数**。这是个常见误解——名字里带 “atomic” 和 “notify”,容易让人联想到 std::condition_variable::notify_all,但两者完全无关。
真正提供 notify_all 的是 std::condition_variable 和 std::condition_variable_any;而 std::atomic 只负责无锁的读写同步,不涉及线程等待/唤醒机制。
想唤醒所有等待线程?用 std::condition_variable::notify_all
如果你的场景是“一个线程改状态,多个线程在等这个状态变化后继续执行”,标准做法是:用 std::atomic 管状态 + std::condition_variable 做等待/唤醒协作。
典型结构如下:
std::atomic<bool> ready{false};
std::mutex mtx;
std::condition_variable cv;
// 等待线程:
std::unique_lock<:mutex> lk(mtx);
cv.wait(lk, []{ return ready.load(); }); // 等待 ready 变 true
// 通知线程:
ready.store(true);
cv.notify_all(); // ✅ 这才是真正的 notify_all
</:mutex></bool>
注意点:
-
cv.wait()必须配合std::mutex使用,内部会自动解锁/加锁 -
notify_all()不保证唤醒后所有线程立即执行——只是解除阻塞,后续仍受调度和锁竞争影响 - 不能在没有对应
wait()调用时提前notify_all(),否则通知丢失(没有线程在等) - 如果只唤醒一个线程,用
cv.notify_one()更轻量
为什么不能只靠 std::atomic 实现“等待-唤醒”
std::atomic 提供的是「原子读写」和「内存序控制」,比如 load()、store()、fetch_add(),但它**不阻塞线程**。你无法写出类似 my_flag.wait_until_true() 这样的代码。
常见错误写法(忙等,浪费 CPU):
while (!flag.load(std::memory_order_acquire)) {
std::this_thread::yield(); // 或更糟:什么都不做空转
}
这不算“唤醒”,只是轮询;notify_all 的意义在于让等待线程**挂起让出 CPU**,直到被显式唤醒。只有 std::condition_variable(配合 mutex)或低层系统原语(如 futex、Windows Event)能实现这点。
替代方案:C++20 的 std::atomic_wait / std::atomic_notify
C++20 引入了真正的原子等待/唤醒原语:std::atomic_wait 和 std::atomic_notify_all,但它们是**自由函数**,不是成员函数,且仅适用于部分 std::atomic 类型(如 bool、整型、指针)。
用法示例:
std::atomic<int> flag{0};
// 等待线程:
std::atomic_wait(&flag, 0); // 等待 flag != 0
// 通知线程:
flag.store(42);
std::atomic_notify_all(&flag); // ✅ C++20 自由函数,参数是指针
</int>
注意事项:
- 需要编译器支持(GCC 11+、Clang 12+、MSVC 19.30+),且开启
-std=c++20 - 不依赖 mutex,但底层仍需 OS 支持(Linux 上映射到 futex)
- 不提供谓词等待(即不能像
cv.wait(..., []{...})那样带条件逻辑),必须自己检查状态变更是否符合预期 - 唤醒后仍需重新 load 判断值,因为存在虚假唤醒可能
最易忽略的一点:std::atomic_notify_all 是函数,不是方法;传参是 &atomic_var,不是 atomic_var.notify_all()——这个地址传参习惯和旧式 C API 一脉相承,但新手常在这里卡住。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











