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++多线程编程中,加锁是为了防止多个线程同时访问共享资源导致数据竞争和未定义行为。常用的加锁方式依赖于标准库中的 头文件提供的工具。下面介绍几种常见的加锁方法及其使用场景。
1. 使用 std::mutex 基本加锁
std::mutex 是最基本的互斥量,用于保护临界区。
示例:
#include #include #include 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++免费学习笔记(深入)”;
2. 使用 std::lock_guard 自动管理锁
推荐使用 std::lock_guard 实现RAII(资源获取即初始化),自动加锁和解锁。
示例:
#include #include #include std::mutex mtx;void print_block(int n) { std::lock_guard guard(mtx); // 构造时加锁,析构时自动解锁 for (int i = 0; i < 5; ++i) { std::cout << "Thread " << n << ": " << i << 'n'; }}
优点:即使函数中途抛出异常,也能保证解锁,避免死锁。
3. 使用 std::unique_lock 更灵活的控制
std::unique_lock 比 lock_guard 更灵活,支持延迟加锁、条件变量配合等。
示例:
std::mutex mtx;std::unique_lock ulock(mtx, std::defer_lock); // 不立即加锁// 后续再决定是否加锁ulock.lock();// ... 操作共享资源ulock.unlock();
适用场景:需要条件判断后再加锁,或与 std::condition_variable 配合使用。
4. 多个互斥量的死锁预防:std::lock
当需要同时锁定多个 mutex 时,使用 std::lock 可避免死锁。
示例:
std::mutex mtx1, mtx2;void thread_func() { std::lock(mtx1, mtx2); // 同时加锁,避免死锁 std::lock_guard lock1(mtx1, std::adopt_lock); std::lock_guard lock2(mtx2, std::adopt_lock); // 使用共享资源}
说明:std::adopt_lock 表示该 lock_guard 接管已持有的锁,不重复加锁。
基本上就这些常用方法。实际开发中优先使用 std::lock_guard 简单安全,复杂场景考虑 std::unique_lock。关键是确保每次访问共享数据都正确加锁,避免竞态条件。
以上就是c++++多线程编程怎么加锁_c++多线程加锁方法的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1477877.html
微信扫一扫
支付宝扫一扫