std::lock_guard适用于固定作用域的简单锁管理,而std::unique_lock提供延迟锁定、手动控制、条件变量配合等高级特性,适用于复杂同步场景。

在C++多线程编程中,
std::unique_lock
std::lock_guard
std::mutex
std::lock_guard
std::unique_lock
在C++中处理多线程同步,互斥锁(
std::mutex
lock()
unlock()
unlock()
std::lock_guard
std::unique_lock
std::lock_guard
std::lock_guard
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex my_mutex;
int shared_data = 0;
void increment_data() {
// std::lock_guard 会在构造时锁定 my_mutex
// 并在函数返回(包括异常)时自动解锁
std::lock_guard<std::mutex> lock(my_mutex);
for (int i = 0; i < 1000; ++i) {
shared_data++;
}
// 无需手动调用 my_mutex.unlock();
}
// int main() {
// std::vector<std::thread> threads;
// for (int i = 0; i < 10; ++i) {
// threads.emplace_back(increment_data);
// }
// for (auto& t : threads) {
// t.join();
// }
// std::cout << "Final shared_data: " << shared_data << std::endl; // 期望 10000
// return 0;
// }std::unique_lock
lock_guard
unique_lock
unique_lock
std::condition_variable
立即学习“C++免费学习笔记(深入)”;
#include <iostream>
#include <mutex>
#include <thread>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void worker_thread() {
std::unique_lock<std::mutex> lock(mtx); // 构造时锁定
std::cout << "Worker: Waiting..." << std::endl;
cv.wait(lock, []{ return ready; }); // 等待期间会自动释放锁,被唤醒时重新获取锁
std::cout << "Worker: Ready and working!" << std::endl;
// ... 执行一些操作 ...
lock.unlock(); // 手动解锁,如果需要提前释放锁
std::cout << "Worker: Lock released early." << std::endl;
// ... 执行不需锁保护的操作 ...
lock.lock(); // 再次锁定
std::cout << "Worker: Lock reacquired." << std::endl;
// ...
}
void main_thread() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(mtx);
ready = true;
std::cout << "Main: Notifying worker." << std::endl;
cv.notify_one();
// lock 在这里作用域结束时自动解锁
}
// int main() {
// std::thread t1(worker_thread);
// std::thread t2(main_thread);
// t1.join();
// t2.join();
// return 0;
// }std::lock_guard
在我看来,
std::lock_guard
lock_guard
适用场景:
lock_guard
lock_guard
lock_guard
局限性: 尽管
lock_guard
lock_guard
lock_guard
std::condition_variable
std::condition_variable::wait()
std::unique_lock
lock_guard
lock_guard
lock_guard
std::unique_lock
lock_guard
我个人觉得,
std::unique_lock
lock_guard
延迟锁定(Deferred Locking):
unique_lock
std::defer_lock
unique_lock
lock()
std::lock()
std::mutex m1, m2;
void complex_operation() {
std::unique_lock<std::mutex> ul1(m1, std::defer_lock); // 构造时不锁定
std::unique_lock<std::mutex> ul2(m2, std::defer_lock); // 构造时不锁定
// 使用 std::lock 尝试同时锁定多个互斥量,避免死锁
std::lock(ul1, ul2); // 成功锁定 ul1 和 ul2
// ... 临界区操作 ...
std::cout << "Both locks acquired." << std::endl;
// ul1 和 ul2 在这里作用域结束时自动解锁
}手动解锁和重新锁定:
unique_lock
lock()
unlock()
std::mutex mtx_manual;
void process_data_with_manual_lock() {
std::unique_lock<std::mutex> lock(mtx_manual); // 构造时锁定
// ... 临界区操作 A ...
std::cout << "Phase A completed with lock." << std::endl;
lock.unlock(); // 提前释放锁
// ... 执行不需要锁保护的操作 B ...
std::cout << "Phase B completed without lock." << std::endl;
lock.lock(); // 重新获取锁
// ... 临界区操作 C ...
std::cout << "Phase C completed with lock again." << std::endl;
}条件变量(std::condition_variable
unique_lock
std::condition_variable::wait()
std::unique_lock
wait()
lock_guard
std::mutex cv_mtx;
std::condition_variable cv_var;
bool data_ready = false;
void consumer() {
std::unique_lock<std::mutex> lock(cv_mtx);
cv_var.wait(lock, []{ return data_ready; }); // 等待并释放锁,唤醒时重新获取
std::cout << "Consumer: Data is ready, processing..." << std::endl;
// ... 处理数据 ...
}
void producer() {
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产时间
std::unique_lock<std::mutex> lock(cv_mtx);
data_ready = true;
std::cout << "Producer: Data produced, notifying consumer." << std::endl;
cv_var.notify_one();
}尝试锁定(Try Locking)和定时锁定(Timed Locking):
unique_lock
try_lock()
try_lock_for()
try_lock_until()
std::mutex mtx_try;
void try_lock_example() {
std::unique_lock<std::mutex> lock(mtx_try, std::defer_lock); // 延迟锁定
if (lock.try_lock()) { // 尝试非阻塞地获取锁
std::cout << "Successfully acquired lock." << std::endl;
// ... 临界区操作 ...
} else {
std::cout << "Failed to acquire lock immediately." << std::endl;
}
// 尝试在100毫秒内获取锁
if (lock.try_lock_for(std::chrono::milliseconds(100))) {
std::cout << "Acquired lock within 100ms." << std::endl;
} else {
std::cout << "Failed to acquire lock within 100ms." << std::endl;
}
}所有权转移(Move Semantics):
unique_lock
unique_lock
std::unique_lock<std::mutex> get_locked_resource(std::mutex& m) {
std::unique_lock<std::mutex> lock(m);
// ... 执行一些初始化操作 ...
return lock; // 返回 unique_lock,所有权转移
}
// void use_resource() {
// std::mutex my_m;
// std::unique_lock<std::mutex> current_lock = get_locked_resource(my_m);
// // current_lock 现在持有锁
// std::cout << "Resource acquired and locked in main." << std::endl;
// }std::unique_lock
std::lock_guard
选择
std::unique_lock
std::lock_guard
我的“最佳实践”和选择指南:
优先选择 std::lock_guard
std::lock_guard
unique_lock
lock_guard
lock_guard
unique_lock
何时考虑 std::unique_lock
std::condition_variable
unique_lock
unique_lock
unique_lock
std::defer_lock
try_lock()
try_lock_for()
try_lock_until()
unique_lock
unlock()
lock()
unique_lock
unique_lock
总结一下我的思考过程:
当我面对一个需要锁保护的代码块时,我首先问自己:“我需要条件变量吗?我需要延迟锁定吗?我需要在中途释放锁吗?我需要尝试获取锁吗?我需要转移锁的所有权吗?”
std::lock_guard
std::unique_lock
记住,代码的清晰度和意图的表达同样重要。
lock_guard
unique_lock
unique_lock
lock_guard
以上就是C++如何使用std::unique_lock和std::lock_guard的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号