各种锁机制

1.互斥锁

1.std::mutex 
mutex mtx
mtx.lock()
mtx.unlock()
2.std::lock_guard 利用RAII技术进行上锁和解锁
声明
template<class Mutex>
class lock_guard;
构造函数
explicit lock_guard(mutex_type& m);
3.互斥锁底层实现
//1:上锁 0:解锁
 bool testAndSet(bool& mutex){
   bool value=mutex;
   mutex=true;
   return value;
}

while(testAndSet(mutex)) ; //如果上锁后有线程去获得锁,则一直while循环
/
临界区
/
mutex=0;  //解锁

2.自旋锁(独占锁)

1.实现
class SpinLock {    
public:
    void lock() 
    {
        while (flag.test_and_set(memory_order_acquire));
                //当一个线程无法获取锁时一直阻塞在while循环
    }
    void unlock() 
    {
        flag.clear(memory_order_release);
    }
private:
    std::atomic_flag flag;
};

2.应用场景
当线程无法获取锁时一直试图去获取锁(忙等待),而不是进入睡眠态,
适用于线程使用锁时间较短的场景(当线程切换开销比较大时)。

3.读写锁

1.实现 利用互斥锁实现读写锁
class RWLOCK{
public:
   RWLOCK():flag(0){}
   void readLock(){
      mtx.lock();
      while(flag<0){
         cond.wait(mtx);
      }
      ++flag;
      mtx.unlock();
   }
   void readUnlock(){
      mtx.lock();
      //最后一个读锁解锁,可以进行写锁上锁
      if(--stat==0){
          cond.notify_all();
      }
   }
   void writeLock(){
      mtx.lock();
      //只有不上锁时才能上写锁
      while(flag!=0){
         cond.wait(mtx);
      }
      flag=-1;
      mtx.unlock();
   }
   void writeUnlock(){
        mtx.lock();  
        flag = 0;  
        cond.notify_all(); // 叫醒所有等待的读和写操作  
        mtx.unlock();  
   }
private:
  atomic<int> flag; //0:无锁 >0:读锁的个数 <0:写锁
  condition_variable cond;
  mutex mtx;
};

4.条件变量

1.常用方法
std::mutex mtx;
std::condition_variable cond;
cond.wait(mtx);
cond.notify_all();
2.为何条件变量要搭配锁使用?

//消费者线程
while(queue.empty()){
    /
         1.
         ...
    /
    cond.wait(mtx);
}

//生产者线程
cond.notify_all()

假设有一个生产者线程和一个消费者线程,消费者此时进入1处,
而此时生产者线程发送唤醒信号,而消费者线程未进入wait态,
就错过了该唤醒状态,此时这个线程就永远阻塞了。
而使用锁,进入wait时就先上锁,然后把线程放入等待队列,然后释放锁,就不会错过唤醒信号。

等待队列的线程竞争锁,谁获取锁谁被唤醒,获取资源,
因此,要用while循环,未被唤醒的线程继续等待下一次被唤醒。
全部评论
太实用了,感谢分享啊
点赞 回复 分享
发布于 2022-08-04 20:20

相关推荐

从小父母离异家里没人管,靠着心里的不安和学校的环境也算是坚持到了学有所成的地步。到了大学环境开始松散不知道该做什么,只觉得在不挂科的基础上能往上考多少就考多少,等到秋招来临才发现自己有多么幼稚无能,今年九月份初才发现自己原来连一个求职的方向都没有。因为之前做过前后端一体的课设,算是有过了解,而对于其他岗位连做什么都不知道,因此这一个半个月在越来越焦虑的同时埋头苦学,事到如今想要活下去我似乎只能走前端这条路了,9月初先是靠着虚假夸大能力的简历得到一些笔试来确定了考察的方向,有一个大厂的无笔试面试最终是拒绝了没有勇气去面对。然后在这个基础上埋头苦学,如今也算是搭好了自己前端学习的框架和思考的瞄,可以逐渐给自己扩展新的知识和能力了,但这并不是一件多好的事儿,因为我发现学的越多越焦虑,学的越多便越无力。因为我感觉我如今努力学习的知识都是竞争对手们早就掌握了的东西,我如今困惑追求答案的难题早就被别人解决。别人早就能得心应手地做出项目而我连思考都会卡壳,看着别人的笔试和面经上那些闻所未闻的题目,我才知道别人到底有多强而我有多幼稚,我什么时候才能达到别人那种堪称熟练的能力呢?而且网上的焦虑越多越多,即便是真有这么高的能力最后也大概落得一个低薪打工人的下场,我真的感到迷茫。秋招都快结束了,而我还在继续痛苦的学习之旅,这些天找前端面试发现似乎问的有些简单跟网上搜到的内容不符(可能因为并不是大厂),我是不是本来就没打算被招所以别人懒得细问呢?我不知道,我只能继续总结下去学习下去,不管如何我都要活下去,如果我能早一些准备就好了,如果暑假能意识到现在这个情况就好了,可惜没有如果。种下一棵树的最好时间是十年前,其次是现在,虽然我相信自己的学习能力,但已经错过了最好的时机,只能在焦虑与痛苦中每天坚持学下去。目前的路还有很长很长,先去把typescript看了,再去巩固vue3的基础,再去练习elementui的使用,如果这能找到实习的话就好了。接下来呢?去学uniapp和小程序,不管如何我都要对得起曾经努力的自己。即便我们都感到痛苦,但我心中还是希望我们都能靠自己的努力来获取自己想要的幸福。
紧张的牛牛等一个of...:在担心什么呢,有一手985的学历在,就算是小厂别人都会要的,咱们双非的人更多,多少还在沉沦的,怕什么了
一句话证明你在找工作
点赞 评论 收藏
分享
11-13 20:16
已编辑
厦门理工学院 软件测试
专业嗎喽:硕佬,把学校背景放后面几段,学校背景双非还学院,让人看了就不想往下看。 把实习经历和个人奖项放前面,用数字化简述自己实习的成果和掌握的技能,比如负责项目一次通过率90%,曾4次发现项目潜在问题风险为公司减少损失等等
点赞 评论 收藏
分享
评论
2
8
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务