首页 > 编程语言 >C++多线程3

C++多线程3

时间:2024-01-20 22:45:27浏览次数:28  
标签:include MyMutex lock C++ guard mutex const 多线程

1 利用栈特性自动释放锁RAII

1.1 什么是RAII

RAII(Resource Acquisition Is Initialization),使用局部对象管理资源的技术称为资源获取既初始化,它的生命周期由操作系统管理,无需人工干预。为什么要引入自动释放锁,因为我们有时会因为忘记释放锁,而造成死锁或内存泄漏。我们先来手动实现,来理解一下它的处理过程
代码如下:

#include<thread>
#include<iostream>
#include <mutex>
#include <shared_mutex>
using namespace std;

class xmux {
public:
	xmux(mutex& mux):mux_ (mux){
		
		
		mux_.lock();
		cout << "lock" << endl;
	}
	~xmux() {
		cout << "unlock" << endl;
		mux_.unlock();
	}
private:
	mutex& mux_;
};
static mutex mux;
void test(int i) {
	xmux mu(ref(mux));
	if (i == 1) {
		cout << i << endl;
		return;
	}
	else {
		cout << "2" << endl;
		return;
	}
}
int main() {
	for (int i = 0; i < 3; i++) {
		thread th(test, i);
		th.detach();
	}
	getchar();
}

运行结果:

1.2 C++11所支持的RAII管理互斥资源lock_guard;

我们先来看一下lock_guard的源码:

_EXPORT_STD template <class _Mutex>
class _NODISCARD_LOCK lock_guard { // class with destructor that unlocks a mutex
public:
    using mutex_type = _Mutex;

    explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
        _MyMutex.lock();
    }

    lock_guard(_Mutex& _Mtx, adopt_lock_t) : _MyMutex(_Mtx) {} // construct but don't lock

    ~lock_guard() noexcept {
        _MyMutex.unlock();
    }

    lock_guard(const lock_guard&)            = delete;
    lock_guard& operator=(const lock_guard&) = delete;

private:
    _Mutex& _MyMutex;
};

我们可以看到它是一个模板函数,意味这lock_guard这个类可以实现其他的锁,比如超时锁,共享锁等。此外它提供了两个构造函数一个实现了正常加锁,另一个不做任何操作,用以处理已经加过锁的mutex。lock_guard(const lock_guard&) = delete;和lock_guard& operator=(const lock_guard&) = delete;表示不允许锁的转移。下面是示例:

标签:include,MyMutex,lock,C++,guard,mutex,const,多线程
From: https://www.cnblogs.com/weakcore/p/17977264

相关文章

  • c++函数模板
    一.模板概念:就是建立通用的摸具,大大提高复用性特点:模板不可以直接使用,它只是一个框架模板的通用并不是万能的c++提供两种模板机制函数模板和类模板二.函数模板作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表作用:建立一个通用函数......
  • 多线程与多进程
    多线程和多进程爬虫在很多场景中,爬虫需要抓取大量的数据,而且需要做大量的分析工作。如果只使用单线程的爬虫,效率会非常低。通常有实用价值的爬虫会使用多线程或多进程,这样可以很多工作同时完成,尤其在多CPU的机器上,执行效率更是惊人。一、线程与进程1、进程计算机程序有静态和......
  • C++U3-第11课-单、双链表
    学习目标 链表概念计算机存储结构 单链表 实现单链表       删除 插入节点  双向链表  实现双链表         [【数据结构-链表】猴子选大王] 【题意分析】通过循环报数的方式每一次剔除......
  • C++编译全过程
    1.源文件.cpp2.预处理:将所有的#include头文件以及宏定义替换成其真正的内容(删除所有的注释、宏扩展、文件包含).i3.汇编:转换为汇编语言.s4.编译:转换为二进制机器码.o(目标文件)5.链接:链接过程将多个目标文件以及所需的库文件(.so等)链接成最终的可执行文件(executablefile)......
  • 关于C++符号表
    符号表是程序/单元中“符号”的列表。符号通常是变量或函数的名称。符号表可用于确定变量或函数在内存中的位置。简而言之,SymbolTable是分配给函数&变量的名称与其在内存中的地址的映射,包括类型、范围和大小等元数据。最终由编译器使用。通常,C或C++编译器将单个源文件编译......
  • C++模板例子
    title:"C++模板例子"date:2023-11-02T01:05:25+08:00tags:["C++"]categories:[]draft:falsetoc:true#include<vector>#include<type_traits>usingnamespacestd;classAA{};classBB{};classTest{public:templ......
  • 【C++入门到精通】 C++入门—命名空间
    前言    前面我们学习了C语言,并且知道了C语言的基础语法与用途。接下来一段时间我们会再来学习一下基于C语言并且根据C语言改造的一门新的语言—C++     硕硕相信只要各位大佬们跟着我的博客看下去,肯定能有不少的收获。二话不说咱们要开车了,坐稳扶好呦C++的发展历......
  • C++常见面试题整理
    1.CPP编译链接过程1.CPP编译链接过程预处理处理以#开头的命令,纯文本替换,类型不安全#pragmalib和#pragmalink除外,#pragmalib用于指定要链接的库,#pragmalink用于指定程序入口(默认入口是main函数,但可以通过该命令修改)都是在链接阶段进行处理编译词法分析,语法分析,......
  • C++11原子变量:线程安全、无锁操作的实例解析
     在C++11中,原子变量(std::atomic)提供了一种线程安全的方式来操作共享变量。下面是一个简单的例子,演示了C++11原子变量的用法。#include<iostream>#include<atomic>#include<thread>std::atomic<int>counter(0);//声明一个原子整数变量voidincrementCounter(int......
  • C++ opencv计算两个cv::Rect的重复面积
    C++ opencv计算两个cv::Rect的重复面积  #include<opencv2/opencv.hpp>#include<iostream>intmain(){//创建两个矩形cv::Rectrect1(10,10,50,50);//(x,y,width,height)cv::Rectrect2(30,30,50,50);//检查两个矩形是否重叠......