C++中std::condition_variable_any、std::lock_guard和std::uni
- 其他
- 2025-08-30 10:27:01

1、背景
在 C++ 多线程编程中,同步 和 互斥 是至关重要的概念。C++ 标准库提供了多种同步机制,其中 std::condition_variable_any、std::lock_guard 和 std::unique_lock 是经常被用到的工具。本文将详细介绍这三者的用途、区别、适用场景,并通过示例展示如何正确使用它们。
2、std::lock_guardstd::lock_guard 是 C++ 提供的一个 RAII(资源获取即初始化)风格的互斥锁管理器,用于在作用域内 自动管理 std::mutex 的加锁和解锁,确保不会发生死锁或者忘记解锁的问题,它是一种轻量级自动管理锁。
#include <iostream> #include <thread> #include <mutex> std::mutex mtx; void print_message(const std::string& msg) { std::lock_guard<std::mutex> lock(mtx); // 自动加锁,作用域结束时自动解锁 std::cout << msg << std::endl; } int main() { std::thread t1(print_message, "Hello from thread 1"); std::thread t2(print_message, "Hello from thread 2"); t1.join(); t2.join(); return 0; }该锁主要适用于短生命周期的互斥操作。
3、std::unique_lock与std::lock_guard相比,std::unique_lock支持更加灵活的互斥锁管理。主要有以下几个功能:
支持 defer_lock(延迟加锁),允许在稍后手动调用 lock();支持手动 unlock(),适用于更复杂的同步场景。 #include <iostream> #include <thread> #include <mutex> std::mutex mtx; void worker() { std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 不自动加锁 std::cout << "Before locking...\n"; lock.lock(); // 需要时手动加锁 std::cout << "Worker thread acquired lock\n"; lock.unlock(); // 需要时手动解锁 std::cout << "Worker thread released lock\n"; } int main() { std::thread t(worker); t.join(); return 0; } 支持 try_lock,尝试加锁但不阻塞; #include <iostream> #include <thread> #include <mutex> #include <chrono> std::mutex mtx; void worker() { std::unique_lock<std::mutex> lock(mtx, std::try_to_lock); // 尝试加锁 if (lock.owns_lock()) { // 判断是否成功加锁 std::cout << "Worker acquired lock\n"; } else { std::cout << "Worker failed to acquire lock\n"; } } int main() { std::unique_lock<std::mutex> main_lock(mtx); // 先加锁,让 worker 线程无法获取锁 std::thread t(worker); std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟主线程持锁一段时间 main_lock.unlock(); // 释放锁 t.join(); return 0; } 支持 timed_lock,尝试在一定时间内加锁; #include <iostream> #include <thread> #include <mutex> #include <chrono> std::mutex mtx; void worker() { std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 延迟加锁 if (lock.try_lock_for(std::chrono::seconds(2))) { // 等待最多2秒尝试加锁 std::cout << "Worker acquired lock\n"; } else { std::cout << "Worker failed to acquire lock within timeout\n"; } } int main() { std::unique_lock<std::mutex> main_lock(mtx); // 先加锁 std::thread t(worker); std::this_thread::sleep_for(std::chrono::seconds(3)); // 持锁超过 worker 的等待时间 main_lock.unlock(); // 释放锁 t.join(); return 0; } 4、std::condition_variable_anystd::condition_variable 只能和 std::unique_lockstd::mutex 结合使用,但是 std::condition_variable_any 可以适配 std::shared_mutex,从而实现 读写者模型。
#include <iostream> #include <thread> #include <shared_mutex> #include <condition_variable> std::shared_mutex rw_mutex; std::condition_variable_any cv; bool data_ready = false; int data = 0; // 读线程(多个线程可以共享读取) void reader(int id) { std::shared_lock<std::shared_mutex> lock(rw_mutex); cv.wait(lock, [] { return data_ready; }); // 等待数据就绪 std::cout << "Reader " << id << " read data: " << data << std::endl; } // 写线程(独占写入) void writer() { std::this_thread::sleep_for(std::chrono::seconds(2)); { std::unique_lock<std::shared_mutex> lock(rw_mutex); data = 42; data_ready = true; } cv.notify_all(); // 唤醒所有等待的读线程 } int main() { std::thread readers[3] = { std::thread(reader, 1), std::thread(reader, 2), std::thread(reader, 3) }; std::thread writer_thread(writer); for (auto& r : readers) r.join(); writer_thread.join(); return 0; } std::condition_variable_any 与 std::condition_variable 的区别 特性std::condition_variablestd::condition_variable_any兼容锁类型只能配合std::unique_lock<std::mutx>兼容所有符合Lockable规范的锁如std::unique_lock<std::shared_mutex>适用范围只能用于std::mutex适用于std::mutex、std::shared_mutex等适用场景经典生产者-消费者模型适用于读写锁等更多场景线程等待允许多个线程等待同一条件允许多个线程等待同一条件 5、结论 如果你只需要在作用域内加锁并确保自动释放,使用 std::lock_guard。如果你需要更灵活的锁管理,如手动解锁或尝试加锁,使用 std::unique_lock。如果你需要线程间的条件同步,使用 std::condition_variable_any或者std::condition_variable,再根据std::mutex和std::shared_mutex哪个可以满足需求决定使用那一个条件变量,std::condition_variable_any比std::condition_variable功能更加强大,因此它的性能开销应该比std::condition_variable更大,因此如果std::condition_variable可以满足需要,最好使用std::condition_variable,否则使用std::condition_variable_any。C++中std::condition_variable_any、std::lock_guard和std::uni由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C++中std::condition_variable_any、std::lock_guard和std::uni”