C++多线程中通过std::mutex、std::lock_guard、std::unique_lock和std::lock实现加锁,防止数据竞争。1. std::mutex提供基础lock/unlock操作,但需手动管理;2. std::lock_guard采用RAII机制,构造时加锁,析构时解锁,异常安全;3. std::unique_lock支持延迟加锁和条件变量配合,灵活性高;4. std::lock用于多个互斥量同时加锁,避免死锁,结合std::adopt_lock由lock_guard接管已获锁。推荐优先使用lock_guard保证安全,复杂场景选用unique_lock,确保共享资源访问始终受保护。

在C++多线程编程中,加锁是为了防止多个线程同时访问共享资源导致数据竞争和未定义行为。常用的加锁方式依赖于标准库中的 <mutex> 头文件提供的工具。下面介绍几种常见的加锁方法及其使用场景。
std::mutex 是最基本的互斥量,用于保护临界区。
示例:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void print_block(int n) {
mtx.lock(); // 手动加锁
for (int i = 0; i < 5; ++i) {
std::cout << "Thread " << n << ": " << i << '\n';
}
mtx.unlock(); // 手动解锁
}
int main() {
std::thread t1(print_block, 1);
std::thread t2(print_block, 2);
t1.join();
t2.join();
return 0;
}
注意:手动调用 lock() 和 unlock() 容易出错,比如异常发生时可能忘记解锁。
立即学习“C++免费学习笔记(深入)”;
推荐使用 std::lock_guard 实现RAII(资源获取即初始化),自动加锁和解锁。
示例:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void print_block(int n) {
std::lock_guard<std::mutex> guard(mtx); // 构造时加锁,析构时自动解锁
for (int i = 0; i < 5; ++i) {
std::cout << "Thread " << n << ": " << i << '\n';
}
}
优点:即使函数中途抛出异常,也能保证解锁,避免死锁。
std::unique_lock 比 lock_guard 更灵活,支持延迟加锁、条件变量配合等。
示例:
std::mutex mtx; std::unique_lock<std::mutex> ulock(mtx, std::defer_lock); // 不立即加锁 // 后续再决定是否加锁 ulock.lock(); // ... 操作共享资源 ulock.unlock();
适用场景:需要条件判断后再加锁,或与 std::condition_variable 配合使用。
当需要同时锁定多个 mutex 时,使用 std::lock 可避免死锁。
示例:
std::mutex mtx1, mtx2;
void thread_func() {
std::lock(mtx1, mtx2); // 同时加锁,避免死锁
std::lock_guard<std::mutex> lock1(mtx1, std::adopt_lock);
std::lock_guard<std::mutex> lock2(mtx2, std::adopt_lock);
// 使用共享资源
}
说明:std::adopt_lock 表示该 lock_guard 接管已持有的锁,不重复加锁。
基本上就这些常用方法。实际开发中优先使用 std::lock_guard 简单安全,复杂场景考虑 std::unique_lock。关键是确保每次访问共享数据都正确加锁,避免竞态条件。
以上就是c++++多线程编程怎么加锁_c++多线程加锁方法的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号