新闻详情

新闻详情

首页 / 资讯中心 / 详情

互斥锁管理之lock_guard和scope_lock学习

发布时间:2026/9/1 18:07:18来源:尧图网络
互斥锁管理之lock_guard和scope_lock学习
前面博客在多线程中处理访问共享资源使用mutex的lock和unlock来对数据进行保护避免数据据竞争。如果对某一段功能代码进行保护每次都要lock和unlock如果忘记unlock了那么多线程访问就卡着永远不会结束了本篇记录一种简便的方法来进行数据保护即lock_guard和scope_lock。先看之前的mutex的示例//lock_guard.cpp lock_guard example //#include iostream // std::cout #include thread // std::thread #include mutex // std::mutex //临界区互斥锁 std::mutex mtx; // mutex for critical section int g_count 0; //自增函数测试 void incrementation() { printf(incrementationstart lock\n); mtx.lock(); for (int i 0; i 1000000; i) { g_count; } //模拟耗时 std::this_thread::sleep_for(std::chrono::seconds(1)); //休眠1秒 printf(incrementationend lock\n); mtx.unlock(); } int main() { std::thread t1(incrementation); std::thread t2(incrementation); t1.join(); t2.join(); //理论应该 2000000不加锁实际永远小于这个数 printf(g_count%d\n, g_count); printf(hello learn mutex\n); return 0; }编译运行如果忘记unlock()了那这个程序就永远不会结束了。1.lock_guard现在把它改成std::lock_guardstd::mutex lock(mtx);一行代码就解决这种问题。//lock_guard.cpp lock_guard example //#include iostream // std::cout #include thread // std::thread #include mutex // std::mutex //临界区互斥锁 std::mutex mtx; // mutex for critical section int g_count 0; //自增函数测试 void incrementation() { printf(incrementationstart lock\n); std::lock_guardstd::mutex lock(mtx); for (int i 0; i 1000000; i) { g_count; } //模拟耗时 std::this_thread::sleep_for(std::chrono::seconds(1)); //休眠1秒 printf(incrementationend lock\n); } int main() { std::thread t1(incrementation); std::thread t2(incrementation); t1.join(); t2.join(); //理论应该 2000000不加锁实际永远小于这个数 printf(g_count%d\n, g_count); printf(hello learn lock_guard\n); return 0; }编译运行运行结果是一样的。lock_guard 是互斥体包装器为在作用域块期间占有互斥体提供便利的 RAII 风格机制。当创建lock_guard 对象时它尝试接收给定互斥体的所有权。当控制离开创建 lock_guard 对象的作用域时销毁 lock_guard 并释放互斥体。2.scope_lock上面介绍的是只有一个互斥体如果有两个互斥体呢lock_guard要写两次例如一个银行转帐系统转帐时既要锁住转出账户也要锁入转入账户不然同时操作就乱了。//scoped_lock.cpp scoped_lock example #include iostream #include thread #include mutex #include vector #include chrono #include memory // 如果需要智能指针 class BankAccount { private: int balance_; mutable std::mutex mtx_; // 加 mutable允许在 const 函数中修改 public: explicit BankAccount(int initial) : balance_(initial) {} void transfer(BankAccount target, int amount) { // 错误示例不要这样写可能死锁 // std::lock_guardstd::mutex lock1(mtx_); // 假设先锁 from // std::lock_guardstd::mutex lock2(target.mtx_); // 再锁 target // 如果另一个线程先锁 target 再锁 from就会死锁 // 正确的 lock_guard 写法需要配合 std::lock std::lock(mtx_, target.mtx_); // 先统一锁定 std::lock_guardstd::mutex lock1(mtx_, std::adopt_lock); // 接管已锁 std::lock_guardstd::mutex lock2(target.mtx_, std::adopt_lock); if (balance_ amount) { balance_ - amount; target.balance_ amount; std::cout [成功] 转账 amount 当前账户余额: balance_ std::endl; } else { std::cout [失败] 余额不足当前余额: balance_ std::endl; } } int getBalance() const { std::lock_guardstd::mutex lock(mtx_); return balance_; } }; int main() { BankAccount accountA(1000); BankAccount accountB(500); std::vectorstd::thread threads; // 线程1A - B 转账 200执行3次 threads.emplace_back([]() { for (int i 0; i 3; i) { accountA.transfer(accountB, 200); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); // 线程2B - A 转账 100执行3次 threads.emplace_back([]() { for (int i 0; i 3; i) { accountB.transfer(accountA, 100); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); // 线程3A - B 转账 300执行2次 threads.emplace_back([]() { for (int i 0; i 2; i) { accountA.transfer(accountB, 300); std::this_thread::sleep_for(std::chrono::milliseconds(15)); } }); for (auto t : threads) { t.join(); } std::cout \n 最终余额 std::endl; std::cout 账户A: accountA.getBalance() std::endl; std::cout 账户B: accountB.getBalance() std::endl; printf(hello learn lock_guard\n); return 0; }编译运行如果是更多个数据项要保护那么又得加多个互斥体这样既窗容易出错也很难维护那边有没有更好的方法呢答案就是用scoped_lock解决这个问题可以同时多个互斥体这是c17的标准。//scoped_lock.cpp scoped_lock example #include iostream #include thread #include mutex #include vector #include chrono #include memory // 如果需要智能指针 class BankAccount { private: int balance_; mutable std::mutex mtx_; // 加 mutable允许在 const 函数中修改 public: explicit BankAccount(int initial) : balance_(initial) {} void transfer(BankAccount target, int amount) { // 使用 std::scoped_lock 同时锁定两个互斥量 std::scoped_lock lock(mtx_, target.mtx_); if (balance_ amount) { balance_ - amount; target.balance_ amount; std::cout [成功] 转账 amount 当前账户余额: balance_ std::endl; } else { std::cout [失败] 余额不足当前余额: balance_ std::endl; } } int getBalance() const { std::lock_guardstd::mutex lock(mtx_); return balance_; } }; int main() { BankAccount accountA(1000); BankAccount accountB(500); std::vectorstd::thread threads; // 线程1A - B 转账 200执行3次 threads.emplace_back([]() { for (int i 0; i 3; i) { accountA.transfer(accountB, 200); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); // 线程2B - A 转账 100执行3次 threads.emplace_back([]() { for (int i 0; i 3; i) { accountB.transfer(accountA, 100); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }); // 线程3A - B 转账 300执行2次 threads.emplace_back([]() { for (int i 0; i 2; i) { accountA.transfer(accountB, 300); std::this_thread::sleep_for(std::chrono::milliseconds(15)); } }); for (auto t : threads) { t.join(); } std::cout \n 最终余额 std::endl; std::cout 账户A: accountA.getBalance() std::endl; std::cout 账户B: accountB.getBalance() std::endl; printf(hello learn lock_guard\n); return 0; }编译运行参考https://cplusplus.com/reference/mutex/lock_guard/https://zh.cppreference.com/cpp/thread/lock_guardhttps://zh.cppreference.com/cpp/thread/scoped_lock
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

pstack验证技能:让AI Agent像真实用户一样验证应用 2026/9/1 18:43:23

pstack验证技能:让AI Agent像真实用户一样验证应用

pstack 这次新增的能力,把“验证”这件事从脚本层提成了“技能层”。过去我们让 Agent 验证应用,要么写死一段测试脚本,要么靠模型现场“自由发挥”,结果经常是:会点、会填,但不知道结果对不对,…

阅读更多 →
用Python+Pygame+OpenCV+GPT打造桌面虚拟数字人 2026/9/1 18:43:23

用Python+Pygame+OpenCV+GPT打造桌面虚拟数字人

简介:本资源是一个基于Python实现的轻量级虚拟数字人直播系统,面向AI初学者、计算机视觉与人机交互方向的学习者及数字内容创作者,解决实时驱动虚拟形象并融合语音交互的核心问题。项目整合OpenCV进行人脸/动作捕捉、Pygame渲染2D虚拟人动画、…

阅读更多 →
GLM-5.3-Flash与Qwen3.8-Flash-Next:架构收敛下的推理效率与选型实践 2026/9/1 18:43:23

GLM-5.3-Flash与Qwen3.8-Flash-Next:架构收敛下的推理效率与选型实践

最近一段时间,不少做 Agent 或者 LLM 应用的同学应该都注意到了同一个现象:在 OpenRouter、ccswitch 这类模型聚合平台上,glm-5.3-flash和qwen3.8-flash-next这两个名字出现得越来越频繁。尤其是社区里有人同时放出两个模型的对比截图后&…

阅读更多 →
SS9G电力机车0K210次铁路摄影实战:机位选择与追焦参数全解析 2026/9/1 18:43:23

SS9G电力机车0K210次铁路摄影实战:机位选择与追焦参数全解析

当你在广州小北天桥等待一列由“烧酒”牵引的绿皮车底时,那种由远及近的轰鸣声,会让之前所有的等候都变得值得。不过,要拍好这样一趟车,光靠运气是不够的。本文将以广铁广段SS9G型0150号电力机车牵引0K210次列车通过广九线小北天桥…

阅读更多 →
基于IP-IQ检测与双闭环控制的并联型有源电力滤波器Simulink仿真 2026/9/1 18:43:23

基于IP-IQ检测与双闭环控制的并联型有源电力滤波器Simulink仿真

并联型有源电力滤波器(APF)是解决谐波污染的主流电力电子装置,而整个仿真研究的关键难点不在主电路拓扑,而在谐波检测方法和控制策略是否能在Simulink中正确闭环。这次我们看的就是一套围绕“IP-IQ谐波检测 电压电流双闭环控制”…

阅读更多 →
扩散智能DiffuSpace联手Acrab让端侧Agent跑出“5倍速”:扩散模型两年内或替代GPT? 2026/9/1 18:40:22

扩散智能DiffuSpace联手Acrab让端侧Agent跑出“5倍速”:扩散模型两年内或替代GPT?

9月1日消息,扩散语言模型团队扩散智能DiffuSpace与亚洲智能体计算平台公司Acrab达成战略合作,双方将推动dLLM在AI PC、智能汽车、机器人及智能家居等端侧AI场景落地,适配测试显示,dLLM可将端侧Agent的运行速度提升5倍。随着dLLM范…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞