第七课:C++多线程独享锁

文章通过洗澡和上厕所的场景比喻,解释了在多线程环境下为何需要使用互斥量(mutex)来防止数据竞争。未加锁的代码可能会导致异常,而使用unique_lock的加锁机制可以确保线程安全。unique_lock的不同构造参数如adopt_lock,defer_lock和try_to_lock展示了在不同情况下的锁管理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、举个例子

1、洗澡和上厕所的案例

1.1、在上厕所的过程需要关门、防止他人看到或者防止洗澡的人进来,总之不能开着门上厕所吧。洗澡也一样,在洗澡的过程,需要关门,再洗澡。洗澡完后,开门出来,上厕所的人再上厕所。

1.2、如果上厕所和洗澡的人,不关上门,那不引发一些不敢想象的画面了。程序也一样引发一些异常。

如下:

#include<thread>
#include<iostream>
#include<string>
#include<mutex>
#include<list>

using namespace std;
using namespace this_thread;

class DoSomething
{
  public:
     void WC()
     {
              for(int i = 0; i < 1000; i++)
              {
                                 
                  cout<<"上厕所"<<endl;

                  num.push_back(i);
                  
              }
     }
    
    void bath()
    {
        for(int i = 0; i < 1000; i++)
        {
            if(!num.empty())
            {
                cout<<"洗澡"<<endl;
                num.pop_back();
            }
            else
            {
                cout<<"厕所在忙"<<endl;
            }
        }
    }
    
    
  protected:
    list<int> num;
    mutex mtx;  //互斥量
};

int main()
{
   DoSomething people;
   thread t1(&DoSomething::WC,&people);
   thread t2(&DoSomething::bath,&people);
    
   t1.join();
   t2.join(); 
    return 0;
}

二、加锁

2.1、如果上厕所和洗澡的人,关上门,他人无法看一些画面了。程序也一样不会引发异常。

如下:

#include<thread>
#include<iostream>
#include<string>
#include<mutex>
#include<list>

using namespace std;
using namespace this_thread;

class DoSomething
{
  public:
     void WC()
     {
              for(int i = 0; i < 1000; i++)
              {
                  
                  unique_lock<mutex> unique(ntx); //unique_lock加锁
                  
                  cout<<"上厕所"<<endl;

                  num.push_back(i);
                   
              }
     }
    
    void bath()
    {
        for(int i = 0; i < 1000; i++)
        {
            if(!num.empty())
            {
                unique_lock<mutex> unique(mtx);  //unique_lock加锁
                cout<<"洗澡"<<endl;
                num.pop_back();
            }
            else
            {
                cout<<"厕所在忙"<<endl;
            }
        }
    }
    
    
  protected:
    list<int> num;
    mutex mtx;  //互斥量
};

int main()
{
   DoSomething people;
   thread t1(&DoSomething::WC,&people);
   thread t2(&DoSomething::bath,&people);
    
   t1.join();
   t2.join(); 
    return 0;
}

三、  unique_lock 其他叁数

 1、已经讲完了 unique_lock 加锁

//1,unique_lock加锁
unique_lock<mutex> unique(ntx);  //unique_lock加锁

2、unique_lock 第二个叁数的第一个  adopt_lock 使用前、先进行lok操作,如果不加会引发中断

void WC()
     {
              for(int i = 0; i < 1000; i++)
              {
                 
                  unique.lock();
                  unique_lock<mutex> unique(ntx,adopt_lock);
                  cout<<"上厕所"<<endl;
                  num.push_back(i);


              }
     }

3、unique_lock 第二个叁数的第二个  defer_lock 需要手动 lock,创建是一个没有lock的锁,相当于只在门上安装了锁,没有上锁。也会引发异常。

     void WC()
     {
              for(int i = 0; i < 1000; i++)
              {

                  unique_lock<mutex> unique(ntx,defer_lock);             
                  unique.lock();
                  cout<<"上厕所"<<endl;
                  num.push_back(i);
                  
              }
     }

3.1、对于一个只在门上安装了锁,没有上锁的门,限于局部范围内方便程序设计。

比如:在做数据共享问题,有些没必要加锁的地方,没必要加锁;有些地方需要加锁、还是要加锁。

void WC()
     {
              for(int i = 0; i < 1000; i++)
              {
                  
                  
                  unique_lock<mutex> unique(ntx,defer_lock);
                  cout<<"上厕所"<<endl;
                  unique.lock();
                  num.push_back(i);
                  unique.unlock();
                  unique.lock();
              }
     }

4、unique_lock 第二个叁数的第三个 try_to_lock 使用前、调用owns_lock()判断

 void WC()
     {
              for(int i = 0; i < 1000; i++)
              {

                  unique_lock<mutex> unique(ntx,try_to_lock);
                  
                  cout<<"上厕所"<<endl;

                  if(unique.owns_lock())
                  {
                       num.push_back(i);
                  }
                 
              }
     }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值