当前位置: 首页 > news >正文

C++多线程编程中的锁详解

在现代软件开发中,多线程编程是提升应用程序性能和响应能力的重要手段。然而,多线程编程也带来了数据竞争和死锁等复杂问题。为了确保线程间的同步和共享数据的一致性,C++标准库提供了多种锁机制。

1. std::mutex

std::mutex是最基础的互斥锁,用于保护共享数据,防止多个线程同时访问该数据。

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void print_thread_id(int id) {mtx.lock();std::cout << "Thread " << id << std::endl;mtx.unlock();
}int main() {std::thread t1(print_thread_id, 1);std::thread t2(print_thread_id, 2);t1.join();t2.join();return 0;
}

在上述代码中,mtx.lock()mtx.unlock()分别用于加锁和解锁,确保同一时刻只有一个线程可以访问临界区(std::cout操作)。

2. std::recursive_mutex

std::recursive_mutex允许同一线程多次获得同一锁,而不会导致死锁。适用于递归调用中需要加锁的场景。

#include <iostream>
#include <thread>
#include <mutex>std::recursive_mutex rec_mtx;void recursive_function(int count) {if (count <= 0) return;rec_mtx.lock();std::cout << "Count: " << count << std::endl;recursive_function(count - 1);rec_mtx.unlock();
}int main() {std::thread t(recursive_function, 5);t.join();return 0;
}

3. std::timed_mutex

std::timed_mutex支持尝试在一定时间内获取锁。这在避免死锁和提高程序响应性方面很有用。

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>std::timed_mutex tmtx;void try_lock_for_example() {if (tmtx.try_lock_for(std::chrono::seconds(1))) {std::cout << "Lock acquired" << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));tmtx.unlock();} else {std::cout << "Failed to acquire lock" << std::endl;}
}int main() {std::thread t1(try_lock_for_example);std::thread t2(try_lock_for_example);t1.join();t2.join();return 0;
}

4. std::recursive_timed_mutex

std::recursive_timed_mutex结合了std::recursive_mutexstd::timed_mutex的特性

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>std::recursive_timed_mutex rtmtx;void recursive_timed_function(int count) {if (count <= 0) return;if (rtmtx.try_lock_for(std::chrono::seconds(1))) {std::cout << "Count: " << count << std::endl;recursive_timed_function(count - 1);rtmtx.unlock();} else {std::cout << "Failed to acquire lock" << std::endl;}
}int main() {std::thread t(recursive_timed_function, 5);t.join();return 0;
}

5. std::shared_mutex(C++17引入)

std::shared_mutex允许多个线程同时读取共享数据,但只允许一个线程写入数据。这种机制适用于读多写少的场景。

#include <iostream>
#include <thread>
#include <shared_mutex>std::shared_mutex smtx;void read_function() {smtx.lock_shared();std::cout << "Reading data" << std::endl;smtx.unlock_shared();
}void write_function() {smtx.lock();std::cout << "Writing data" << std::endl;smtx.unlock();
}int main() {std::thread t1(read_function);std::thread t2(read_function);std::thread t3(write_function);t1.join();t2.join();t3.join();return 0;
}

6. std::shared_timed_mutex(C++14引入)

std::shared_timed_mutex结合了std::shared_mutexstd::timed_mutex的特性。

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <chrono>std::shared_timed_mutex stmtx;void shared_timed_read_function() {if (stmtx.try_lock_shared_for(std::chrono::seconds(1))) {std::cout << "Reading data" << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));stmtx.unlock_shared();} else {std::cout << "Failed to acquire shared lock" << std::endl;}
}void shared_timed_write_function() {if (stmtx.try_lock_for(std::chrono::seconds(1))) {std::cout << "Writing data" << std::endl;std::this_thread::sleep_for(std::chrono::seconds(2));stmtx.unlock();} else {std::cout << "Failed to acquire exclusive lock" << std::endl;}
}int main() {std::thread t1(shared_timed_read_function);std::thread t2(shared_timed_read_function);std::thread t3(shared_timed_write_function);t1.join();t2.join();t3.join();return 0;
}

7. std::lock_guard

std::lock_guard提供一种异常安全的方式来管理锁的生命周期,通常用于自动解锁。

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void lock_guard_example() {std::lock_guard<std::mutex> lock(mtx);std::cout << "Lock acquired using lock_guard" << std::endl;// mtx is automatically unlocked when lock goes out of scope
}int main() {std::thread t(lock_guard_example);t.join();return 0;
}

8. std::unique_lock

std::unique_lockstd::lock_guard更加灵活,支持延迟加锁、解锁和重新加锁。

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void unique_lock_example() {std::unique_lock<std::mutex> lock(mtx);std::cout << "Lock acquired using unique_lock" << std::endl;lock.unlock();std::cout << "Lock released" << std::endl;lock.lock();std::cout << "Lock reacquired" << std::endl;
}int main() {std::thread t(unique_lock_example);t.join();return 0;
}

9. std::shared_lock(C++17引入)

std::shared_lock用于管理共享互斥量(std::shared_mutexstd::shared_timed_mutex),提供了一种简单的方式来处理读锁。

#include <iostream>
#include <thread>
#include <shared_mutex>std::shared_mutex smtx;void shared_lock_example() {std::shared_lock<std::shared_mutex> lock(smtx);std::cout << "Shared lock acquired" << std::endl;
}int main() {std::thread t1(shared_lock_example);std::thread t2(shared_lock_example);t1.join();t2.join();return 0;
}

结论

C++标准库提供了多种锁机制,帮助开发者在多线程环境中确保数据的一致性和线程的同步。根据具体的应用场景选择合适的锁,可以有效地避免数据竞争和死锁问题,从而编写出高效、安全的多线程程序。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 并发编程面试题1
  • 在C#中,如何优化对象的创建和销毁以提高性能?
  • c# excel转pdf
  • 16QAM实验报告【附全部MATLAB代码】
  • 高阶面试-hw算法整理
  • 2013年全国大学生数学建模竞赛B题碎纸片复原(含word论文和源代码资源)
  • Python PDF Magic:合并和拆分随心所欲
  • windows server——5.DNS管理器域名解析搭建网站
  • 快速创建 vue 项目并添加 Dockerfile 文件
  • 手动构建线性回归(PyTorch)
  • 如何搭建一个RADIUS服务器?
  • vue3封装el-table及实现表头自定义筛选
  • CSP-J模拟赛day1
  • 【计算机网络】0 课程主要内容(自顶向下方法,中科大郑烇、杨坚)(待)
  • Flutter 开源库学习
  • 10个确保微服务与容器安全的最佳实践
  • 30秒的PHP代码片段(1)数组 - Array
  • android 一些 utils
  • ComponentOne 2017 V2版本正式发布
  • Git初体验
  • happypack两次报错的问题
  • JavaScript 奇技淫巧
  • leetcode98. Validate Binary Search Tree
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • react-core-image-upload 一款轻量级图片上传裁剪插件
  • Terraform入门 - 1. 安装Terraform
  • v-if和v-for连用出现的问题
  • yii2中session跨域名的问题
  • 百度小程序遇到的问题
  • 多线程事务回滚
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 精彩代码 vue.js
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 数据库写操作弃用“SELECT ... FOR UPDATE”解决方案
  • 网页视频流m3u8/ts视频下载
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 温故知新之javascript面向对象
  • 小李飞刀:SQL题目刷起来!
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 如何正确理解,内页权重高于首页?
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​Linux·i2c驱动架构​
  • #Linux(帮助手册)
  • #Ubuntu(修改root信息)
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • $.ajax()方法详解
  • (1)bark-ml
  • (function(){})()的分步解析
  • (javaweb)Http协议
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF