C++ 代码中如何使用互斥锁std::mutex和独占锁std::unique_lock

2024-01-03 22:20

本文主要是介绍C++ 代码中如何使用互斥锁std::mutex和独占锁std::unique_lock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

创建一个C++线程需要传入几个参数?
如何理解和使用C++线程循环
C++ 类 函数 变量 进程 线程
C++关于锁和互斥量你真的理解了吗?

在这个例子中,我们将创建一个简单的类,该类包含一个共享数据成员和两个方法,这两个方法将通过互斥锁来同步对共享数据的访问。

  1. SharedResource 类包含一个整数数据成员和一个互斥锁。
  2. incrementdecrement 方法使用 std::unique_lock 来锁定互斥锁。这保证了当一个线程在执行这些方法时,其他线程不能同时执行它们。
  3. main 函数直接创建了两个线程,分别调用 SharedResource 类的 increment 和 decrement 方法。
    通过使用 std::thread 的构造函数,我们将类的成员函数和对象的地址传递给线程。这样做允许线程直接调用这些成员函数。
  4. 通过使用互斥锁,我们确保了对共享资源的安全访问,避免了数据竞争。这个程序演示了在多线程环境中如何安全地访问和修改共享数据。
  • t1.join();:这一行确保主线程等待 t1 线程结束。t1 是之前启动的线程,它执行了 incrementFunction 或类的 increment 方法。

  • t2.join();:这一行确保主线程在继续执行之前,会等待 t2 线程结束。t2 是执行 decrementFunction 或类的 decrement 方法的线程。

使用 join() 的主要原因和优势是:

  1. 确保线程完成join() 确保程序中的其他逻辑只有在相关的线程执行完毕后才会执行。这对于依赖于线程结果的情况非常重要。

  2. 防止程序过早结束:在主线程(通常是程序的入口点)中使用 join() 防止了主线程(程序)在子线程完成它们的工作之前结束。

  3. 避免资源泄露:如果一个线程结束了它的执行,但没有被 join()detach()(另一种处理线程的方式),程序将终止并显示一个错误。使用 join() 确保每个线程都有机会正确完成,避免了潜在的资源泄露。

在多数情况下,如果你创建了线程,你应该在某个点上调用 join()(或 detach(),取决于具体情况),以确保线程得到正确处理。在你的代码中,join() 被用来确保 t1t2 线程在程序结束前完成它们的任务。

#include <iostream>
#include <mutex>
#include <thread>class SharedResource {
private:int data;std::mutex mtx;public:SharedResource() : data(0) {}void increment() {std::unique_lock<std::mutex> lock(mtx);++data;std::cout << "Data incremented to " << data << std::endl;// lock is released when it goes out of scope}void decrement() {std::unique_lock<std::mutex> lock(mtx);--data;std::cout << "Data decremented to " << data << std::endl;// lock is released when it goes out of scope}int getData() const {return data;}
};int main() {SharedResource resource;std::thread t1(&SharedResource::increment, &resource);std::thread t2(&SharedResource::decrement, &resource);t1.join();t2.join();std::cout << "Final data value: " << resource.getData() << std::endl;return 0;
}

在 C++ 多线程编程中,join() 方法是 std::thread 类的一个非常重要的成员函数。当你在一个线程对象上调用 join() 方法时,调用它的线程(通常是主线程)将等待直到与该线程对象相关联的线程完成其执行。换句话说,join() 使得启动线程(例如主线程)暂停执行,直到被 join() 的线程结束其任务。

在你的代码中:

t1.join();
t2.join();

这篇关于C++ 代码中如何使用互斥锁std::mutex和独占锁std::unique_lock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部