mutex 互斥

2023-11-17

互斥

互斥算法避免多个线程同时访问共享资源。这会避免数据竞争,并提供线程间的同步支持。


mutex 类

mutex 类是能用于保护共享数据免受从多个线程同时访问的同步原语。

mutex 提供排他性非递归所有权语义:

调用方线程从它成功调用 lock 或 try_lock 开始,到它调用 unlock 为止占有 mutex 。
线程占有 mutex 时,所有其他线程若试图要求 mutex 的所有权,则将阻塞(对于 lock 的调用)或收到 false 返回值(对于 try_lock ).
调用方线程在调用 lock 或 try_lock 前必须不占有 mutex 。
若 mutex 在仍为任何线程所占有时即被销毁,或在占有 mutex 时线程终止,则行为未定义。 mutex 类满足互斥 (Mutex) 和标准布局类型 (StandardLayoutType) 的全部要求。

std::mutex 既不可复制亦不可移动。


要求

头文件: <mutex>

命名空间: std


公共方法

名称 描述
lock 锁定互斥,若互斥不可用则阻塞
try_lock 尝试锁定互斥,若互斥不可用则返回
unlock 解锁互斥
native_handle 返回底层实现定义的原生句柄

注意

通常不直接使用 std::mutex : std::unique_lock 、 std::lock_guard 或 std::scoped_lock (C++17 起)以更加异常安全的方式管理锁定。


lock

锁定互斥。若另一线程已锁定互斥,则到 lock 的调用将阻塞执行,直至获得锁。

若 lock 为已占有 mutex 的线程调用,则行为未定义:例如,程序可能死锁。鼓励能检测非法使用的实现抛出以 resource_deadlock_would_occur 为错误条件的 std::system_error ,而不是死锁。

同一互斥上先前的 unlock() 操作同步于(定义于 std::memory_order )此操作。

unlock

解锁互斥。

互斥必须为当前执行线程所锁定,否则行为未定义。

此操作同步于(定义于 std::memory_order )任何后继的取得同一互斥所有权的锁操作。

#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>

int g_num = 0;  // 被 g_num_mutex 所保护
std::mutex g_num_mutex;

void slow_increment(int id)
{
	for (int i = 0; i < 3; ++i) {
		g_num_mutex.lock();	// lock锁定

		// lock到unlock之间的代码只有一个线程能执行
		++g_num;
		std::cout << id << " => " << g_num << '\n';

		g_num_mutex.unlock(); // unlock解锁

		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
}

int main()
{
	std::thread t1(slow_increment, 0);
	std::thread t2(slow_increment, 1);
	t1.join();
	t2.join();
}
Output
0 => 1
1 => 2
1 => 3
0 => 4
0 => 5
1 => 6

try_lock

尝试锁定互斥。立即返回。成功获得锁时返回 true ,否则返回 false 。

允许此函数虚假地失败而返回 false ,即使互斥当前未为任何其他线程所锁定。

若已占有 mutex 的线程调用 try_lock ,则行为未定义。

若此操作返回 true ,则同一互斥上的先前 unlock() 操作同步于(定义于 std::memory_order )它。注意若此操作返回 false ,则先前的 lock() 不与之同步。

#include <iostream> // std::cout
#include <chrono>
#include <mutex>
#include <thread>

std::chrono::milliseconds interval(100);

std::mutex mutex;
int job_shared = 0;	// 两个线程都能修改 'job_shared',
					// mutex 将保护此变量

int job_exclusive = 0;	// 只有一个线程能修改 'job_exclusive'
						// 不需要保护

// 此线程能修改 'job_shared' 和 'job_exclusive'
void job_1()
{
	std::this_thread::sleep_for(interval); // 0.1秒延迟, 令 'job_2' 先持锁

	while (true) {
		// 尝试锁定 mutex 以修改 'job_shared'
		if (mutex.try_lock()) {
			std::cout << "job shared (" << job_shared << ")\n";
			mutex.unlock();
			return;
		}
		else {
			// 不能获取锁以修改 'job_shared'
			// 但有其他工作可做
			++job_exclusive;
			std::cout << "job exclusive (" << job_exclusive << ")\n";
			std::this_thread::sleep_for(interval);
		}
	}
}

// 此线程只能修改 'job_shared'
void job_2()
{
	mutex.lock();
	std::this_thread::sleep_for(5 * interval); // 0.5秒后unlock
	++job_shared;
	mutex.unlock();
}

int main()
{
	std::thread thread_1(job_1);
	std::thread thread_2(job_2);

	thread_1.join();
	thread_2.join();
}
Output
job exclusive (1)
job exclusive (2)
job exclusive (3)
job exclusive (4)
job shared (1)

相关参考

微软文档(mutex)

cppreference(mutex)

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

mutex 互斥 的相关文章

  • 虚拟机ubuntu18.04桥接模式详解

    背景 虚拟机ubuntu18 04桥接模式下 配置静态ip 配置静态ip vim etc network interfaces 具体配置如下 auto lo iface lo inet loopback auto ens33 iface e
  • 算法题Day6-第三大的数

    给定一个非空数组 返回此数组中第三大的数 如果不存在 则返回数组中最大的数 要求算法时间复杂度必须是O n 示例 1 输入 3 2 1 输出 1 解释 第三大的数是 1 示例 2 输入 1 2 输出 2 解释 第三大的数不存在 所以返回最大
  • SQL查询结果按照指定内容排序

    一般来说 我们在开发SQL脚本的时候 遇到需要排序的内容 用order by需要排序的字段就可以满足我们排序的需求 asc为升序 desc为降序 不指定关键字默认为升序 但是有时候 我们需要的排序不仅仅是升序和降序 asc与desc并不能满
  • Kibana 7.X 导出CSV报告

    背景 由于有时候需要基于日志做一些处理 由官网得知 ES7 3 0发布的新特性 从保存的搜索中导出CSV 我们的Kibana刚好是7 3 0 于是将自己的使用经验及解决的问题 分享给有需要的小伙伴 一 使用步骤 1 1 保存搜索 Disco
  • Spring Cloud 与 Dubbo 冲突吗——强强联合

    微服务开发选型 到底是基于 Dubbo 还是 Spring Cloud 相信不少开发的小伙伴都有拿这两个项目作过作比较的经历 本章节就带你走近这两个项目 二者究竟是竞争发展还是融合共赢 项目发展简介 我们还是先来看看 Dubbo 的发展历史
  • (递归)杨辉三角实现

    问题描述 杨辉三角形又称Pascal三角形 它的第i 1行是 a b i的展开式的系数 它的一个重要性质是 三角形中的每个数字等于它两肩上的数字相加 下面给出了杨辉三角形的前4行 1 1 1 1 2 1 1 3 3 1 思路 可以用二维数组
  • c++ string替换指定字符串

    string fnd dataset string rep labels string buf d data dataset ii jpg buf buf replace buf find fnd fnd length rep 去掉由于wi
  • ubuntu不息屏、隐藏其他软件图标 小技巧

    1 有时想安静的写写代码 但是这时候ubuntu老是自动进入休眠状态 这是你可以进入 设置 gt system setting gt power gt Brightness Lock 或者直接搜索Brightness Lock 将Turn
  • Latex学习笔记二——Overleaf在线练习

    锵锵 本文是基于Overleaf的Latex学习的第二部分 目录 1 结构化文档 2 添加图表 让论文更生动可读 2 1 Graphics 2 2 Floats 2 3 Tables 3 Bibliographies 1 结构化文档 这一部
  • SQl语句查询重复数据 只显示其中一条

    SQL查询重复数据 只显示其中一条 有重复数据主要有以下几种情况 1 存在两条完全相同的纪录 这是最简单的一种情况 用关键字distinct就可以去掉 example select distinct from table 表名 where
  • 电子专业 英语词汇大全(持续更新)

    文章目录 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 序号 词汇的领域 1 软件 软件开发 2 计算机 计算机网络 多媒体 3 单片机 电子 电子仪器 通信 A 序号 词汇 描述
  • GD32 和 ST32的区别

    TIM重载寄存器 复位值不一样 xxx xxx xxx xxxx
  • 服务器如何查询配置信息吗,如何查看linux服务器的配置信息

    如何查看linux服务器的配置信息 内容精选 换一换 本节介绍如何查看云服务器的mac地址 云服务器的mac地址不支持修改 登录Linux云服务器 执行以下命令 查看云服务器的mac地址 ifconfig查看MAC地址ifconfig登录L
  • 解决子盒子把父盒子撑破问题

    场景 div class demo 父盒子 div class box div 子盒子 div 当你设置子盒子的padding和border的时候就会把父盒子撑破 因为子盒子的宽度是100 而浏览器的默认盒模型为content box 即内
  • 遇到argument of type ‘Word2Vec‘ is not iterable不要慌。。。

    重要的事开头说 不要以为是返回值的问题或参数的问题 因为很有可能你学的那个是个老文档 现在已经改变函数了 报这个错我这里的原因是word2vec构造出来的模型不能遍历 原来代码 if word in model model就是用word2v

随机推荐

  • 设计模式【精简概述, 应用场景】(个人总结)

    声明 1 本文为我的个人复习总结 并非那种从零基础开始普及知识内容详细全面 言辞官方的文章 2 由于是个人总结 所以用最精简的话语来写文章 3 若有错误不当之处 请指出 Gof23设计模式分为三类 创建型模式 负责组件的创建 结构型模式 负
  • C++实现裴波那契数列——自顶向下递归

    随便写一下 没有整理 注释比较多 大家按需自取 include
  • gitlab 12.0.3_GitLab 13.0强调安全性

    gitlab 12 0 3 GitLab已发布其devops平台的13 0版 该平台集成了用于软件开发 部署和项目管理的工具 GitLab 13 0添加了许多新的安全性和协作功能 GitLab结合了Git开源分布式版本控制系统 持续集成和持
  • C/C++2019秋招面试题集合01

    C C 2019秋招面试题集合01 8 19 腾讯 提前批 客户端开发 1 给定一个字符串数组 和一个子串 求字符串中是否存在子串 如果存在则返回首个匹配到的索引位置 否则 返回 1 不能调用库函数 例如 字符串数组 Integrity P
  • 【小练习】windows与linux进行socket文件传输

    在Windows与Linux使用socket通信基础上 添加文件传输功能 需要进行简单的交互 目录 程序效果 实现流程 样例代码 测试用例 参考资料 程序效果 Windows客户端可以从Linux服务器端索要文件 也可以发送文件至Linux
  • matlab算法集

    matlab 算法集 自定义函数 1 高斯消去法 注 高斯消元法可以用来找出一个可逆矩阵的逆矩阵 设A 为一个N N的矩阵 其逆矩阵可被两个分块矩阵表示出来 将一个N N单位矩阵 放在A 的右手边 形成一个N 2N的分块矩阵B A I 经过
  • HTML的作用与功能,css是什么?有什么作用?

    css是什么 有什么作用 下面本篇文章就来给大家介绍一下CSS样式表 让大家对CSS有一个简单的了解 希望对大家有所帮助 一 CSS定义与解释 CSS是Cascading Style Sheets 层叠样式表单 的简称 CSS就是一种叫做样
  • 生成式对抗网络(GANs)综述

    GAN GAN简介 生成式对抗网络 Generative adversarial networks GANs 的核心思想源自于零和博弈 包括生成器和判别器两个部分 生成器接收随机变量并生成 假 样本 判别器则用于判断输入的样本是真实的还是合
  • main() 方法为什么必须是静态的

    静态 如果您声明方法 子类 块或静态变量 则将其与类一起加载 在Java中 只要需要调用 实例 方法 就应该实例化 包含它的 类并调用它 如果我们需要不实例化地调用方法 则它应该是静态的 此外 静态方法与类一起被加载到内存中 对于main方
  • EduSoho网校系统安装教程(三):nginx配置

    Ubuntu下nginx的配置 安装nginx sudo apt get install nginx 配置Nginx sudo vim etc nginx nginx conf 在http 添加 client max body size 1
  • mysql复制表的几种方式

    mysql复制表的几种方式 所描述的方法还请实际测试一下再使用 1 复制表结构及数据到新表 CREATE TABLE 新表SELECT FROM 旧表 这种方法会将oldtable中所有的内容都拷贝过来 当然我们可以用delete from
  • Exception对性能的影响

    我们知道 当程序发生异常时 会通过new调用异常的构造方法 在堆内存区域创建一个异常实例 而构造方法都是默认调用基类的Throwalbe的构造方法 下面我们看一下代码 public Throwable fillInStackTrace pu
  • webpack4 devserver 如何拦截请求 添加请求headers

    v4官网 https v4 webpack docschina org configuration dev server devserver proxy devServer 配置 devServer host 127 0 0 1 https
  • 使用ffmpeg将mp4转为m3u8并播放

    ffmpeg 下载地址 https ffmpeg zeranoe com builds 这个是我自己的ffmpeg 有积分的大佬可以任性下载 ffmpeg压缩包 下载解压之后需要将ffmpeg添加到环境变量中 cmd中输入 ffmpeg v
  • R语言与数据分析实战4-变量的创建与修改

    第1关 创建新变量 在进行实际的数据分析时 我们会经常需要创建新变量或者为当前存在的变量变换新的取值 这就好比你是一个厨师 现在你要创新菜式 需要做一些新的厨房模具或者是改良当前已有的厨具来进行烹饪 对于创建新变量 其实原理非常简单 大家只
  • shell-2-文本处理工具

    主题 文本处理工具 一 grep grep 全局搜索正则表达式 固定字符表示通用匹配 whatis grep man grep 查看grep用法 正则表达式分为两种 传统 扩展正则表达式 对应的 有两个命令 grep 传统 和 egrep
  • nginx应用指南

    一 nginx基本简述 最新更新 请点击这个里1 概念 nginx是一个开源且高性能 可靠的HTTP中间件 代理服务 开源 直接获取源代码 高性能 支持海量并发 2 nginx应用场景 静态处理 反向代理 负载均衡 资源缓存 安全防护 访问
  • Gson解析JSON数据中动态未知字段key的方法

    有时在解析json数据中的字段key是动态可变的时候 由于Gson是使用静态注解的方式来设置实体对象的 因此我们很难直接对返回的类型来判断 但Gson在解析过程中如果不知道解析的字段 就会将所有变量存储在一个Map中 我们只要实例化这个ma
  • 严格模式和非严格模式区别

    严格模式和非严格模式有什么区别 严格模式对正常的 JavaScript语义做了一些更改 首先 严格模式通过抛出错误来消除了一些原有静默错误 其次 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷 有时候 相同的代码 严格模
  • mutex 互斥

    文章目录 互斥 mutex 类 要求 公共方法 注意 lock unlock try lock 相关参考 互斥 互斥算法避免多个线程同时访问共享资源 这会避免数据竞争 并提供线程间的同步支持 mutex 类 mutex 类是能用于保护共享数