06C++11多线程编程之lock_guard类模板

2023-10-31

06C++11多线程编程之lock_guard类模板

1 lock_guard概念

  • 1)lock_guard是一个类模板,它是mutex的进化版,自动lock()和unlock。类似独占型智能指针unique_ptr,是一个保姆。在lock_guard生命周期结束自动释放锁,智能指针自动释放new出来的内存。
  • 2)使用lock_guard后不能再使用lock和unlock,否则会出现程序不稳定甚至崩溃。
    下面写一段lock_guard的伪代码:
#include <iostream>
#include <mutex>
using namespace std;

int main(){

	std::mutex mymutex;
	{
		std::lock_guard<mutex> lGuard(mymutex);//构造时自动上锁,出去花括号后lGuard生命周期结束,锁在析构自动释放,这就是lock_guard。
	}
	
	//接下来为非共享代码,因为上面已经被释放锁
	
	return 0;
}

2 lock_guard的共享代码案例
上一篇我们说到使用mutex的lock和unlock正确的保护了共享代码,下面我们将其替换为lock_guard。

#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>

using namespace std;

//准备用成员函数作为线程函数的方法写线程,成为消息处理类
class A{
public:
	//把收到的消息入到一个队列的线程
	void inMsgRecvQueue(){
		for (int i = 0; i < 10000; i++){
			cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;

			{
				lock_guard<mutex> lGuard(my_mutex);
				//my_mutex.lock();
				msgRecvQueue.push_back(i); //存放消息
				//my_mutex.unlock();
			}

		}
	}

	//将共享的代码放到一个函数处理,方便上锁解锁
	bool outMsgLULProc(int &command){
		lock_guard<mutex> lGuard(my_mutex);
		//my_mutex.lock();
		if (!msgRecvQueue.empty()){
			int command = msgRecvQueue.front();
			msgRecvQueue.pop_front();
			//my_mutex.unlock();  //所有分支都必须有unlock()
			return true;
		}
		//my_mutex.unlock();
		return false;
	}

	//把数据从消息队列取出的线程
	void outMsgRecvQueue(){
		int command = 0;
		for (int i = 0; i < 10000; i++){
			bool result = outMsgLULProc(command);
			if (result == true){
				cout << "outMsgRecvQueue()执行,取出一个元素" << endl;
				//处理数据
				//这里有可能也有需要共享的代码段
			}
			else{
				//消息队列为空
				cout << "inMsgRecvQueue()执行,但目前消息队列中为空!" << i << endl;
			}
		}
		cout << "end!" << endl;
	}

private:
	std::list<int> msgRecvQueue;//容器(消息队列),代表玩家发送过来的命令。
	std::mutex my_mutex;
};

int main(){
	A myobja;

	std::thread myOutMsgObj(&A::outMsgRecvQueue, &myobja);//第二个参数,地址,才能保证线程里用的是同一个对象
	std::thread myInMsgObj(&A::inMsgRecvQueue, &myobja);

	myOutMsgObj.join();
	myInMsgObj.join();

	cout << "主线程执行!" << endl;

	return 0;
}

结果可以看到是正常运行的。
在这里插入图片描述

3 lock_guard的参数2std::adopt_lock

  • 1)lock_guard的参数2只有一个std::adopt_lock。
  • 2)std::adopt_lock是个结构体对象,起一个标志作用,表示这个互斥量已经lock(),不需要在std::lock_guard构造里再次lock()。

代码案例看我的下一篇死锁文章,里面详细说了std::lock配合lock_guard的参数2解决死锁并且自动解锁的案例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

06C++11多线程编程之lock_guard类模板 的相关文章

  • WindowsError:[错误 126] 使用 ctypes 加载操作系统时

    python代码无法在Windows 7平台上运行 def libSO lib ctypes cdll LoadLibrary ConsoleApplication2 so lib cfoo2 1 3 当我尝试运行它时 得到来自python
  • 更新面板工作速度非常慢

    我正在编写一个用户可以注册的应用程序 注册时 可以选择多个选项 并根据这些注册字段可见或不可见以及是否必需 我想出了一个想法 所有字段都将位于 updatePanel 中 当用户更改注册选项时 我将在服务器端设置这些字段的可见性 它可以工作
  • 尝试了解使用服务打开对话框

    我已经阅读了有关使用 mvvm 模式打开对话框的讨论 我看过几个使用服务的示例 但我不明白所有部分如何组合在一起 我发布这个问题寻求指导 以了解我应该阅读哪些内容 以更好地理解我所缺少的内容 我将在下面发布我所拥有的内容 它确实有效 但从我
  • 使用 CMake 时如何导出 Emscripten 中的 C 函数

    In 本教程 https emscripten org docs porting connecting cpp and javascript Interacting with code html interacting with code
  • 如何在类文件中使用 Url.Action() ?

    如何在 MVC 项目的类文件中使用 Url Action Like namespace 3harf public class myFunction public static void CheckUserAdminPanelPermissi
  • 传递 constexpr 对象

    我决定给予新的C 14的定义constexpr旋转并充分利用它 我决定编写一个小的编译时字符串解析器 然而 我正在努力保持我的对象constexpr将其传递给函数时 考虑以下代码 include
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • extern 声明和函数定义都在同一文件中

    我只是浏览了一下gcc源文件 在gcc c 我发现了类似的东西 extern int main int char int main int argc char argv 现在我的疑问是extern是告诉编译器特定的函数不在这个文件中 但可以
  • 即使没有异步,CallContext.LogicalGetData 也会恢复。为什么?

    我注意到CallContext LogicalSetData LogicalGetData不按照我期望的方式工作 内部设置的值async方法得到恢复即使没有异步或任何类型的线程切换 无论如何 这是一个简单的例子 using System u
  • 如何使用 Regex.Replace 从字符串中删除数字?

    我需要使用Regex Replace从字符串中删除所有数字和符号 输入示例 123 abcd33输出示例 abcd 请尝试以下操作 var output Regex Replace input d string Empty The d标识符
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 在 .NET MAUI 中实现 TouchTracking

    我一直致力于将我们的应用程序从 Xamarin Forms 迁移到 NET MAUI 我们的应用程序几乎没有绘图功能 用户可以用手指进行绘图 我们用了TouchTrackingXamarin Forms 中的 nuget 包 但与 NET
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se
  • 模板类中的无效数据类型生成编译时错误?

    我正在使用 C 创建一个字符串类 我希望该类仅接受数据类型 char 和 wchar t 并且我希望编译器在编译时使用 error 捕获任何无效数据类型 我不喜欢使用assert 我怎样才能做到这一点 您可以使用静态断言 促进提供一个 ht
  • 使动态创建的链接标签在 Winforms 中可点击

    我正在制作一个程序 允许用户单击由动态链接标签创建的公司名称 在我想知道如何做到这一点之前 我从未在 C 中使用过链接标签 可为特定用户生成的业务数量各不相同 因此每个用户的链接标签数量并不相同 然后我想捕获业务 ID 以进行 Json 调
  • C++:二叉树所有节点值的总和

    我正在准备面试 我被一个二叉树问题困住了 我们如何计算二叉树所有节点中存在的值的总和 优雅的递归解决方案 伪代码 def sum node if node NULL return 0 return node gt value sum nod
  • 如何在 sql azure 上运行 aspnet_regsql? [复制]

    这个问题在这里已经有答案了 可能的重复 将 ASP NET 成员资格数据库迁移到 SQL Azure https stackoverflow com questions 10140774 migrating asp net membersh
  • 无法将字符串文字分配给装箱的 std::string 向量

    这是我的类型系统的简化版本 include
  • 在 System.Type 上使用条件断点时出错

    这是函数 public void Init System Type Type this Type Type BuildFieldAttributes BuildDataColumns FieldAttributes 我在第一行设置了一个断点
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names

随机推荐

  • mysql修改root密码的语句

    ALTER USER root localhost IDENTIFIED WITH mysql native password BY 新密码 其中 localhost 字符 有的小伙伴可能遇到过无法通过navicat连接Linux中的MyS
  • 单点登录SSO:可一键运行的完整代码

    单点登录方案不同于一个普通站点 它的部署比较繁琐 涉及到好几个站点 要改host 安装证书 配置HTTPS 看到的不少这方面示例都是基于HTTP的 不认同这种简化 1 它体现不出混合HTTP HTTPS时 单点注销要注意处理的问题 2 做单
  • 【Node.js】下载安装及简单使用

    说起Node js 它是当前市面上非常受欢迎的框架 允许我们使用JavaScript搭建后端应用 它有着种种优点 诸如 非阻塞I O 事件驱动 跨平台 高性能 单线程 等等等等 不过现在我们不必执拗与关心这些优点的含义 当务之急是先上手他
  • conda加速设置

    Conda作为使用最为便捷的python环境管理工具 可以协助我们很方便的下载安装第三方库 软件包等操作 但其在下载资源的过程中速度不言而喻 尤其是在更换国内源的情况下 下载速度没有实质性的改变是很令人头疼的一件事 Mamba 树眼镜蛇 能
  • (tensorflow学习)用Object Detection API实现摄像头实时物体检测

    对于物体识别 谷歌已经有训练好的模型供我们使用 图方便不想自己训练的可以直接使用 说实话 装这个tensorflow真心麻烦 我建议用anaconda环境搭建 还要注意装的话装1 几的版本就可 用gpu跑的话注意显卡型号和版本是否兼容 真是
  • 【C++】内存管理

    目录 一 C C 内存分布 二 C语言中动态内存管理方式 三 C 中动态内存管理 1 开辟空间 2 释放空间 四 operator new与operator delete函数 五 内存泄漏 1 什么是内存泄漏 2 如何避免内存泄漏 总结 一
  • Python的getattr方法

    getattr是Python中的内置函数 用于获取一个对象的属性值 这个函数是动态获取属性的一种方式 特别适用于你事先不知道要获取哪个属性 或者属性名是在运行时确定的情况 使用方法 getattr object name default o
  • 资产安全 错题点

    数据所有者 1 决定谁有权访问信息系统 2 对资产负有最终责任 PS 对资产负有最终责任的 高级管理层 数据所有者 首选管理层 3 行为规则 制定规则 以便用于主体的数据或信息的适当使用及保护 4 决定数据的级别 每年回顾确保数据分级的正确
  • 【国产化踩坑记】openEuler系统安装,nvidia驱动,cuda,anaconda安装步骤记录

    1 openEuler安装步骤 尝试安装了openEuler20 03和22 03两个版本 在摸索的过程中总结了一下步骤 以及相关问题的解决方案 进行简单记录 便于后续使用 1 openEuler20 03安装步骤 网络配置以及可视化操作界
  • Segmentation fault (core dumped) 错误的一种解决场景

    错误类型 Segmentation fault core dumped 产生原因 Segmentation fault 段错误 Core Dump 核心转储 是操作系统在进程收到某些信号而终止运行时 将此时进程地址空间的内容以及有关进程状态
  • Springboot+Axios双token解决token过期续签问题

    后端分离使用token进行登录验证时 由于token存在过期时间 每次token过期都需要用户重新登录的话 用户体验很不友好 假如token能跟session一样 如果用户持续在进行操作 就自动延长有效时间 就可以解决问题 但是 token
  • qt利用腾讯云服务器实现不同局域网的通信(tcp)

    网上大多数关于qt通信的文章都是同一局域网通信 这种根本没有达到自己想象中的那种通信的要求 不同局域网的通信 这里用到的方法是客户端发送消息给服务器 然后服务器再发送给另一个局域网的客户 首先我们需要购买一个腾讯云服务器 并在自己电脑登录腾
  • Python记11(网络传输大文件

    客户端 import socket tqdm os 传输数据分隔符 separator
  • log4j2入门(三) PatternLayout输出格式详解

    摘要 本节介绍Log4j的输出格式的详细说明 1 PatternLayout参数 charset 指定字符集 pattern 指定格式 alwaysWriteExceptions 默认为true 输出异常 header 可选项 包含在每个日
  • connect和bind

    UDP 考虑以下情形 我们使用UDP写一个echo程序 客户端模型 while fget sendto recvfrom 如果服务器进程没有启动会如何 通过截包发现服务器响应一个icmp port unreachable 不过这个ICMP错
  • java: javamail 1.6.2 Create Receive Email using jdk 19

    接收邮件 中文是乱码 未解决 param pop3Host pop 163 com param storeType pop3 param user geovindu 163 com param password geovindu autho
  • 安装DevEco Studio 3.0 Beta2

    引言 鸿蒙应用程序前端 北向开发 的开发环境是华为提供的HUAWEI DevEco Studio DevEco Studio支持Windows和macOS系统 本文记录了DevEco Studio 3 0 Beta2在Windows操作系统
  • 学习笔记 JavaScript ES6 NRM源切换

    NRM npm registry manager 镜像源管理工具 两种切换方式 一 终端里输入如下命令即可切换至淘宝镜像源 mac下测试通过 npm config set registry http registry npm taobao
  • krita windows编译源码

    Qt系列文章目录 文章目录 Qt系列文章目录 前言 一 krita 二 krita源码编译 1 Windows下编译 1 编译准备 2 相关命令 使用CMake编译krita 重新编译 使用CMkae bash find package Z
  • 06C++11多线程编程之lock_guard类模板

    06C 11多线程编程之lock guard类模板 1 lock guard概念 1 lock guard是一个类模板 它是mutex的进化版 自动lock 和unlock 类似独占型智能指针unique ptr 是一个保姆 在lock g