引入
在 C++20 标准中,<atomic> 头文件被增强,加入了新的功能以支持更复杂的并发场景。其中,std::atomic<T>::wait 函数是一个用来实现无锁条件等待的机制。利用这一功能,线程可以在某个特定的原子变量值没有发生变化时主动挂起自己,从而实现高效的条件同步。这种机制为开发者提供了一种优于传统锁或信号量的方式,降低了对系统资源的消耗,提高了应用程序的性能。
1. 特性与函数介绍
1.1 特性
- 无锁等待机制:当线程调用
wait等待时,它将检查指定的原子变量的值。如果该值未改变,线程将被挂起,直到其他线程通知它继续运行。 - 减少资源占用:与传统的循环检查或主动争用不同,
wait函数有效地减少了 CPU 时间的浪费,提高了系统效率。 - 安全性:
wait函数是在原子操作的上下文中管理的,确保了并发场景中的数据安全性。
1.2 函数语法
std::atomic<T>::wait 的基本用法如下:
#include <atomic>
namespace std {
template<typename T>
class atomic {
public:
void wait(T expected_value, std::chrono::milliseconds timeout = std::chrono::milliseconds{-1});
};
}
- 参数:
expected_value:线程希望原子变量保持的值。当原子变量值变为其他值时,线程会唤醒。timeout(可选):允许的等待时间。如果为负数,表示等待无限长的时间。
2. 完整示例代码
以下示例展示了如何使用 std::atomic<T>::wait 实现条件等待:
#include <iostream>
#include <atomic>
#include <thread>
#include <chrono>
std::atomic<int> sharedValue(0);
void waitingThread() {
std::cout << "Waiting thread waiting for sharedValue to change..." << std::endl;
sharedValue.wait(0); // 等待 sharedValue 为 0
std::cout << "Waiting thread awakened! sharedValue is now: " << sharedValue.load() << std::endl;
}
void notifyingThread() {
std::this_thread::sleep_for(std::chrono::seconds(2)); // 确保 waitingThread 首先挂起
sharedValue.store(1); // 改变 sharedValue 的值
std::cout << "Notifying thread changed sharedValue to 1." << std::endl;
}
int main() {
std::thread waitThread(waitingThread);
std::thread notifyThread(notifyingThread);
waitThread.join();
notifyThread.join();
std::cout << "Main thread ends." << std::endl;
return 0;
}
3. 代码解析
-
引入头文件:
- 代码开始时包括
<atomic>,<thread>和<chrono>头文件,以支持原子操作和多线程功能。
- 代码开始时包括
-
定义原子变量:
- 使用
std::atomic<int> sharedValue(0)创建一个原子变量,以保证在多线程环境下的安全操作。
- 使用
-
定义线程函数:
waitingThread中调用sharedValue.wait(0),它将挂起,直到sharedValue的值不再为 0。notifyingThread创建一个 2 秒的延迟后,将sharedValue的值更改为 1,随后唤醒等待的线程。
-
主函数创建线程:
- 在
main中,首先创建等待线程和通知线程,然后通过join()方法等待这两个线程完成。
- 在
4. 适用场景分析
4.1 高效的条件变量
std::atomic<T>::wait 特别适用于需要高效条件等待的场景,如生产者-消费者模式,在此环境中,线程可以在等待某个条件时不会占用 CPU 资源。
4.2 减少不断轮询
通过无锁的方式,wait 可以代替传统的条件变量和轮询机制,消耗更少的 CPU 时间,方便处理瞬态变化。
4.3 优化复杂的同步需求
在某些复杂的多线程数据结构中,元素之间可能有非常复杂的依赖关系。使用 wait 描述这些依赖关系时,可以更加自然且高效。
5. 总结
std::atomic<T>::wait 是 C++20 中一个强大而灵活的同步机制,使得线程能以最低的资源占用推迟执行。结合原子操作,利用 wait 函数的无锁等待特性,开发者能够构建出高效的多线程应用程序,有利于在处理并发时减少开销,提高程序的响应能力。掌握和灵活应用这一特性,对于希望提高 C++ 并发程序效率并保持良好性能的开发者来说,具有重要意义。随着开发者更深入地探索无锁编程范式,std::atomic<T>::wait 在未来的多线程应用中必将发挥越来越大的作用。



没有回复内容