C++ 并发编程,std::unique_lock与std::lock_guard区别示例

2024-03-30 20:08

本文主要是介绍C++ 并发编程,std::unique_lock与std::lock_guard区别示例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

平时看代码时,也会使用到std::lock_guard,但是std::unique_lock用的比较少。在看并发编程,这里总结一下。方便后续使用。

std::unique_lock也可以提供自动加锁、解锁功能,比std::lock_guard更加灵活。

std::lock_guard

std::lock_guard是RAII模板类的简单实现,功能简单。

1.std::lock_guard 在构造函数中进行加锁,析构函数中进行解锁。
2.锁在多线程编程中,使用较多,因此c++11提供了lock_guard模板类;在实际编程中,我们也可以根据自己的场景编写resource_guard RAII类,避免忘掉释放资源。

下面是一个使用std::lock_guard的代码例子,1+2+ .. + 100的多线程实现,每个num只能由一个线程处理。:

#include <thread>
#include <mutex>
#include <vector>
#include <iostream>
#include <algorithm>std::mutex my_lock;void add(int &num, int &sum){while(true){std::lock_guard<std::mutex> lock(my_lock);  if (num < 100){ //运行条件num += 1;sum += num;}   else {  //退出条件break;}   }   
}int main(){int sum = 0;int num = 0;std::vector<std::thread> ver;   //保存线程的vectorfor(int i = 0; i < 20; ++i){std::thread t = std::thread(add, std::ref(num), std::ref(sum));ver.emplace_back(std::move(t)); //保存线程}   std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //joinstd::cout << sum << std::endl;
}

std::unique_lock

类 unique_lock 是通用互斥包装器,允许延迟锁定、锁定的有时限尝试、递归锁定、所有权转移和与条件变量一同使用
unique_lock比lock_guard使用更加灵活,功能更加强大。
使用unique_lock需要付出更多的时间、性能成本。

下面是try_lock的使用例子。

#include <iostream>       // std::cout
#include <thread>         // std::thread
#include <mutex>          // std::mutex, std::unique_lock
#include <vector>std::mutex mtx;           // mutex for critical section
std::once_flag flag;void print_block (int n, char c) {//unique_lock有多组构造函数, 这里std::defer_lock不设置锁状态std::unique_lock<std::mutex> my_lock (mtx, std::defer_lock);//尝试加锁, 如果加锁成功则执行//(适合定时执行一个job的场景, 一个线程执行就可以, 可以用更新时间戳辅助)if(my_lock.try_lock()){for (int i=0; i<n; ++i)std::cout << c;std::cout << '\n';}
}void run_one(int &n){std::call_once(flag, [&n]{n=n+1;}); //只执行一次, 适合延迟加载; 多线程static变量情况
}int main () {std::vector<std::thread> ver;int num = 0;for (auto i = 0; i < 10; ++i){ver.emplace_back(print_block,50,'*');ver.emplace_back(run_one, std::ref(num));}for (auto &t : ver){t.join();}std::cout << num << std::endl;return 0;
}

转载自:C++ 并发编程,std::unique_lock与std::lock_guard区别示例 - 旭东的博客 - 博客园

这篇关于C++ 并发编程,std::unique_lock与std::lock_guard区别示例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/862452

相关文章

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

分辨率三兄弟LPI、DPI 和 PPI有什么区别? 搞清分辨率的那些事儿

《分辨率三兄弟LPI、DPI和PPI有什么区别?搞清分辨率的那些事儿》分辨率这个东西,真的是让人又爱又恨,为了搞清楚它,我可是翻阅了不少资料,最后发现“小7的背包”的解释最让我茅塞顿开,于是,我... 在谈到分辨率时,我们经常会遇到三个相似的缩写:PPI、DPI 和 LPI。虽然它们看起来差不多,但实际应用

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

golang 日志log与logrus示例详解

《golang日志log与logrus示例详解》log是Go语言标准库中一个简单的日志库,本文给大家介绍golang日志log与logrus示例详解,感兴趣的朋友一起看看吧... 目录一、Go 标准库 log 详解1. 功能特点2. 常用函数3. 示例代码4. 优势和局限二、第三方库 logrus 详解1.

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.