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

相关文章:

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

在现代软件开发中&#xff0c;多线程编程是提升应用程序性能和响应能力的重要手段。然而&#xff0c;多线程编程也带来了数据竞争和死锁等复杂问题。为了确保线程间的同步和共享数据的一致性&#xff0c;C标准库提供了多种锁机制。 1. std::mutex std::mutex是最基础的互斥锁…...

van-dialog 组件调用报错

报错截图 报错原因 这个警告表明 vue 在渲染页面时遇到了一个未知的自定义组件 <van-dialog>&#xff0c;并且提示可能是由于未正确注册该组件导致的。在 vue 中&#xff0c;当我们使用自定义组件时&#xff0c;需要先在 vue 实例中注册这些组件&#xff0c;以便 vue 能…...

【Django】在vscode中运行调试Django项目(命令及图形方式)

文章目录 命令方式图形方式默认8000端口设置自定义端口 命令方式 python manage.py runserver图形方式 默认8000端口 设置自定义端口...

麦田物语第十三天

系列文章目录 麦田物语第十三天 文章目录 系列文章目录一、实现根据物品详情显示 ItemTooltip1.ItemTooltips脚本编写二、制作 Player 的动画一、实现根据物品详情显示 ItemTooltip 1.ItemTooltips脚本编写 首先创建Scripts->Inventory->UI->ItemTooltip脚本,然后…...

【Git多人协作开发】不同的分支下的多人协作开发模式

目录 0.前言背景 1.开发者1☞完成准备工作&协作开发 1.1查看分支情况 1.2创建本地分支feature-1 1.3三板斧 1.4push推本地分支feature-1到远程仓库 2.开发者2☞完成准备工作&协作开发 2.1创建本地分支feature-2 2.2三板斧 2.2push推送本地feature-2到远程仓库…...

Lua 复数计算器

Lua复数计算器 主要包括复数的加减乘除操作&#xff0c;以及打印 编写复数类 -- ***** 元类 ***** Complex {real 0, imag 0}-- 构造函数 function Complex:new(real, imag)local o o or {}o.real real or 0o.imag imag or 0setmetatable(o, self)self.__index selfr…...

深入MySQL中的IF和IFNULL函数

在数据库查询中&#xff0c;我们经常需要根据条件来决定数据的显示方式。MySQL提供了多种内置函数来帮助我们实现这种条件逻辑&#xff0c;其中IF和IFNULL是两个非常有用的函数。在这篇博客中&#xff0c;我们将深入探讨这两个函数的用法和它们在实际查询中的应用。 IF函数 I…...

AI多模态实战教程:面壁智能MiniCPM-V多模态大模型问答交互、llama.cpp模型量化和推理

一、项目简介 MiniCPM-V 系列是专为视觉-语⾔理解设计的多模态⼤型语⾔模型&#xff08;MLLMs&#xff09;&#xff0c;提供⾼质量的⽂本输出&#xff0c;已发布4个版本。 1.1 主要模型及特性 &#xff08;1&#xff09;MiniCPM-Llama3-V 2.5&#xff1a; 参数规模: 8B性能…...

Docker 搭建Elasticsearch详细步骤

本章教程使用Docker搭建Elasticsearch环境。 一、拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.8.2二、运行容器 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-n...

mysql中提供的函数

文章目录 1.聚合函数2.字符串函数3.数值函数4.日期函数5.流程函数 MySQL 是一个功能强大的关系型数据库管理系统&#xff0c;其中包含了丰富的内置函数&#xff0c;用于处理各种数据操作和查询。这些函数可以分为多种类型&#xff0c;包括字符串函数、数值函数、日期和时间函数…...

加速下载,揭秘Internet Download Manager2024下载器的威力!

1. Internet Download Manager&#xff08;IDM&#xff09;是一款广受欢迎的下载管理软件&#xff0c;以其强大的下载加速功能和用户友好的界面著称。 IDM马丁正版下载如下: https://wm.makeding.com/iclk/?zoneid34275 idm最新绿色版一键安装包链接&#xff1a;抓紧保存以…...

oracle 宽表设计

Oracle宽表设计主要涉及到数据库表或视图中字段&#xff08;列&#xff09;数量较多的情况。在Oracle 23c及以后的版本中&#xff0c;数据库表或视图中允许的最大列数已增加到4096&#xff0c;这为宽表设计提供了更大的灵活性。以下是对Oracle宽表设计的详细分析&#xff1a; …...

winrar安装好后,鼠标右键没有弹出解压的选项

本来安装挺好的&#xff0c;可以正常使用&#xff0c;有天我把winrar相关的文件挪了个位置&#xff0c;就不能正常使用了。 然后我去应用里面找&#xff0c;找到应用标识了&#xff0c;但是找不到对应的文件夹&#xff08;因为我挪到另外一个文件夹里了&#xff09;。 于是我找…...

数字图像处理笔记(一)---- 图像数字化与显示

系列文章目录 数字图像处理学习笔记&#xff08;一&#xff09;---- 图像数字化与显示 数字图像处理笔记&#xff08;二&#xff09;---- 像素加图像统计特征 数字图像处理笔记&#xff08;三) ---- 傅里叶变换的基本原理 文章目录 系列文章目录前言一、数字图像处理二、图像数…...

Unity UGUI 之 事件接口

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是事件接口&…...

Hadoop、HDFS、MapReduce 大数据解决方案

本心、输入输出、结果 文章目录 Hadoop、HDFS、MapReduce 大数据解决方案前言HadoopHadoop 主要组件的Web UI端口和一些基本信息MapReduceMapReduce的核心思想MapReduce的工作流程MapReduce的优缺点Hadoop、HDFS、MapReduce 大数据解决方案 编辑 | 简简单单 Online zuozuo 地址…...

Dubbo SPI 之负载均衡

1. 背景介绍 在分布式系统中&#xff0c;负载均衡是一项核心技术&#xff0c;旨在将请求合理地分配到多个服务实例上&#xff0c;以提高系统的性能和可靠性。Dubbo 作为一个高性能的 Java RPC 框架&#xff0c;提供了多种负载均衡策略来满足不同的业务需求。本文将深入探讨 Du…...

规范:前后端接口规范

1、前言 随着互联网的高速发展&#xff0c;前端页面的展示、交互体验越来越灵活、炫丽&#xff0c;响应体验也要求越来越高&#xff0c;后端服务的高并发、高可用、高性能、高扩展等特性的要求也愈加苛刻&#xff0c;从而导致前后端研发各自专注于自己擅长的领域深耕细作。 然…...

Python --NumPy库基础方法(2)

NumPy Numpy(Numerical Python) 是科学计算基础库&#xff0c;提供大量科学计算相关功能&#xff0c;比如数据统计&#xff0c;随机数生成等。其提供最核心类型为多维数组类型&#xff08;ndarray&#xff09;&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;Numpy支持向…...

音视频入门基础:H.264专题(15)——FFmpeg源码中通过SPS属性获取视频帧率的实现

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

Qemu arm操作系统开发环境

使用qemu虚拟arm硬件比较合适。 步骤如下&#xff1a; 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载&#xff0c;下载地址&#xff1a;https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)

旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据&#xff01;该数据集源自2025年4月发表于《地理学报》的论文成果…...

[拓扑优化] 1.概述

常见的拓扑优化方法有&#xff1a;均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有&#xff1a;有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...