• C++多线程01


    1 互斥量的基本概念

    把共享数据锁住,操作数据,解锁

    其他线程等待解锁,上锁,操作,解锁

    2 互斥量的用法

    #include  
    mutex mtx;
    
    //lock()与unlock()成对使用
    
    mtx.lock()
    //......
    mtx.unlock()
        
    //等价于   不能和lock()混用
    lock_guard<mutex> lk(mtx);  //生成lock_guard的对象lk 类的构造函数里执行了mutex::lock()   析构函数里执行了mutex::unlock()  return 之前才能析构  
    //可以利用{} 对数据进行析构  可以提前结束lock_guard的生命周期 可以达到提前析构  若后面还有大量代码  若为return 无需{}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    为了防止大家忘记unlock(),引入了lock_guard() 类似于独占式智能指针 会自动lock

    3 死锁

    一个互斥量就是一把锁

    死锁必须要至少有两把锁 也就是两个互斥量

    两把锁 金锁 银锁

    两个线程 A B

    (1)线程A 缩金锁 将要去锁银锁

    //出现了上下文切换

    (2)线程B 锁银锁 将要去锁金锁

    //发生了死锁

    (3)线程A因为拿不到银锁 后面的代码有解锁金锁但是走不下去

    ​ 线程B因为拿不到金锁 后面的代码有解锁银锁但是走不下去

    mutex mtx1;
    mutex mtx2;
    
    //线程A
    mtx1.lock();
    //.......
    mtx2.lock();
    mtx2.unlock();
    mtx1.unlock();
        
    //线程B
    mtx2.lock();
    mtx1.lock();
    mtx1.unlock();
    mtx2.unlock();
    
    //lock()函数
    lock(mtx1, mtx2);
    mtx2.unlock();
    mtx1.unlock();
    
    
    //等同于adopt_lock
    lock(mtx1, mtx2);
    lock_guard<mutex> lk1(mtx1, adopt_lock);  //取代mtx2.unlock()
    lock_guard<mutex> lk2(mtx2, adopt_lock);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    如何解决问题:

    保持一样的顺序 都是先锁1后锁2

    lock()函数可以同时锁住多个变量 至少两个 防止出现死锁

    ​ 如果互斥量中有一个没锁住,会立刻释放已经锁住的互斥量 要么两个互斥量都锁柱 要么两个互斥量都没锁住

    adopt_lock 是一个结构体对象 表示对象已经lock过了 不需要在lock_guard中再对对象进程lock(), unlock()照常

    4 参考资料

    https://www.bilibili.com/video/BV1Yb411L7ak?p=7&vd_source=3faf892a87f05b733e8d196b0c30eada

    第1节 第2节 join detach joinable

    第5节 mutex 死锁

    第8节 condition_variable wait notify_one notify_all

    第10节 第11节 tomic 原子操作

    第12节 临界区

    第13节 线程池 多线程

  • 相关阅读:
    Nginx内存池:内存分配方案 | 小块内存分配方案
    git 快速构造10个文件
    Logistic回归实战---疝气病症预测病马的死亡率
    基于Python的算术编码的设计与实现
    事件分发机制原理
    如何在Ubuntu部署Emlog,并将本地博客发布至公网可远程访问
    elasticsearch安装(centos7)
    既要便捷、安全+智能,也要颜值,萤石发布北斗星人脸锁DL30F和极光人脸视频锁Y3000FV
    力扣刷题day27|455分发饼干、376摆动序列、53最大子序和
    实验一、综合实验【Process on】
  • 原文地址:https://blog.csdn.net/qq_41945053/article/details/126709242