首页 > 编程语言 >C++11 同步与互斥

C++11 同步与互斥

时间:2023-08-04 12:12:39浏览次数:41  
标签:11 std lock C++ 互斥 线程 mutex unique

C++11 同步与互斥

1. std中的锁

1.1 锁是实现互斥的方法,在std中实现了多种基本锁如下:

  1. std::mutex:最基本的互斥锁,只能在同一线程中进行加锁和解锁操作。

  2. std::recursive_mutex:递归互斥锁,允许同一线程多次加锁,但必须在同一线程中解锁相同次数。

  3. std::timed_mutex:定时互斥锁,允许线程尝试加锁一段时间,如果超时则放弃锁。

  4. std::recursive_timed_mutex:递归定时互斥锁,结合了递归和定时互斥锁的特性。

  5. std::shared_mutex:共享互斥锁,允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。当一个线程持有写入权限时,其他所有线程都无法获取读取或写入权限,直到该线程释放写入权限。注意这是一个读写分离锁,即多个线程可以同时读取共享数据,但只有一个线程可以写入共享数据。当一个线程正在写入共享数据时,其他线程必须等待该线程完成写入操作后才能进行读取或写入操作。

  6. std::shared_timed_mutex:定时共享互斥锁,结合了共享和定时互斥锁的特性。

    这些锁类型都是线程安全的,可以在多线程环境下使用。选择哪种锁类型取决于具体的应用场景和需求。

1.2 锁的封装

为了更方便的管理互斥锁的生命周期,具有RAII特性,即在对象构造时获取资源,在对象析构时释放资源,从而保证资源的正确获取和释放。他利用此原理在析构函数中释放了锁,即可以达到自动释放锁的效果。

  • std::unique_lock<std::mutex> lock(mutex_)

    可以在构造函数中传入一个互斥锁对象,当std::unique_lock对象被销毁时(出了作用域会自动销毁),它会自动释放互斥锁。同时,std::unique_lock还提供了lock()unlock()方法,可以手动控制互斥锁的加锁和解锁。

    /*unique_lock简单实现*/
    template<class Mutex>
    class unique_lock { 
    public:
    	explicit unique_lock(Mutex& m) : mutex_(m) {
        	mutex_.lock();    
        }   
        ~unique_lock() {  
        	mutex_.unlock();    
        } 
    private: 
    	Mutex& mutex_; 
    };
    
  • std::lock_guard<std::mutex> lock(mutex_).当std::lock_guard对象被销毁时,互斥锁会自动解锁。这样可以确保在std::lock_guard对象的生命周期内,互斥锁一直处于锁定状态,从而避免了忘记解锁的问题。

  • std::scoped_lock也是一个模板类,用于管理多个互斥锁。在创建std::scoped_lock对象时,需要传入多个互斥锁对象,该对象会在std::scoped_lock的构造函数中被锁定,当std::scoped_lock对象被销毁时,所有互斥锁会自动解锁。这样可以确保在std::scoped_lock对象的生命周期内,所有互斥锁都处于锁定状态,从而避免了死锁的问题。需要注意的是,std::scoped_lock可以同时锁定多个互斥锁,但是不能锁定同一个互斥锁多次,否则会导致死锁。

标签:11,std,lock,C++,互斥,线程,mutex,unique
From: https://www.cnblogs.com/fireinstone/p/17605545.html

相关文章

  • ChatGPT 问答00011 Spring框架事件驱动使用案例
    以下是一个使用Spring框架的事件驱动机制的简单案例:定义事件类:publicclassOrderEventextendsApplicationEvent{privateOrderorder;publicOrderEvent(Objectsource,Orderorder){super(source);this.order=order;}public......
  • C++ Toolkit zz
    所谓“工欲善其事,必先利其器”,从程序员的角度来讲,好工具的使用总会给人带来事半功倍的效果。面对众多工具/软件,我们应该如何取舍呢。前不久,笔者在csdn的c++论坛发了一篇贴文,以期能征求大家的广泛意见,得到了不错的反响。本文在对该贴进行整理的基础上,又做了一些补充。在这里要特别......
  • c++算法之离散化
    什么是离散化?离散化,故离散数学,其中的“离散”就是不连续的意思。离散化可以保持原数值之间相对大小关系不变的情况下将其映射成正整数。也就是给可能用到的数值按大小关系分配一个编号,来代替原数值进行各种操作。离散化步骤:1.排序2.去重3.归位举一个例子:将{4000,201,11......
  • C++ 重写、隐藏、覆盖
    1.基本概念:1.1重载重载:是指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。示例:classA{public:voidtest(inti);voidtest(doublei);//overloadvoidtest(inti,doubl......
  • AI-11. 优化算法
    优化算法对于深度学习非常重要。一方面,训练复杂的深度学习模型可能需要数小时、几天甚至数周。优化算法的性能直接影响模型的训练效率。另一方面,了解不同优化算法的原则及其超参数的作用将使我们能够以有针对性的方式调整超参数,以提高深度学习模型的性能。11.1. 优化和深度学习......
  • c++ 箭头运算符
    C++中箭头运算符的含义与用法讲解_C语言_脚本之家(jb51.net)C++中箭头运算符->,相当于把解引用和成员访问符两个操作符结合在一起,换句话说,p->func()和(*p).func()所表示的意思一样。例如:12345classA{public:func();}123456clas......
  • c++数组作为函数参数
    intsum_arr(intarr[],intn){ inttotal=0; for(inti=0;i<n;i++){ total=total+arr[i]; } returntotal;}方括号指出arr是一个数组,而方括号为空则表明,可以将任何长度的数组传递给该函数,n代表数组的长度。实际数组名就是指针,解释为其第一个元素的地址。int......
  • C++11
    1.VariadicTemplate可以传入任意数量的参数,并且参数的类型不定。voidprintX(){}template<typenameT,typename...Types>voidprintX(constT&firstArg,constTypes&...args){cout<<firstArg<<endl;printX(args...);}其中,...是pack包,用于模板参数中(typenam......
  • C++面试八股文:如何实现一个strncpy函数?
    C++面试八股文:如何实现一个strncpy函数?某日二师兄参加XXX科技公司的C++工程师开发岗位第31面:面试官:strcpy函数使用过吧?二师兄:用过。面试官:这个函数有什么作用?二师兄:主要用做字符串复制,将于字符从一个位置复制到另一个位置。面试官:strncpy函数也使用过吧,和strcpy有......
  • C++入门到放弃(08)——类成员:const 和 static用法
    ​1.常量成员const类的常量成员,具备以下特性:1.1.const成员必须被初始化1.2.const成员只能在初始化列表中赋值1.3.const成员不能在构造函数原型中赋值1.4.const成员初始化之后无法更改classConstMember{public:ConstMember(intnum=0):m_num(num)......