互斥器类

互斥器类

 

通常,在多线程任务中,常常为了保证临界区,需要使用一定的手法限制多个进程或者线程的访问,常用的手法通常是互斥,即使用C++中的mutex:

#include <mutex>
using namespace std;

mutex mu;
mu.lock();
...
mu.unlock();

首先来看一个例子,在程序运行过程中,某个需要锁的函数在处理数据时发生了异常:

mutex mu;
try{
   mu.lock();
   cout<<"lock"<<endl;
   throw exception();
   cout<<"unlock"<<endl;
   mu.unlock();
}
catch(...){}
system("pause");
return 0;

结果:程序可能只上锁,而没有正常解锁,导致死锁的发生。

 

当然这是不希望发生的情况,我们可以在catch的部分同样进行解锁操作,如下:

catch(...){
   cout<<"unlock"<<endl;
   mu.unlock(); //解锁操作,防止死锁
}

此时程序的运行是正常的:

 

但是这就意味着,我们需要在每个异常处理的catch块内都写一个解锁的语句。如果说我们都记得写上该语句固然是好事,但是如果说该语句在某处漏掉了,那么死锁的结局仍可能会发生。为了避免这种情况的发生,需要怎么做呢?

互斥器类就诞生了!

class Locks
{
public:
    Locks(mutex* mu):plock(mu,unLock){
        Lock(plock.get());
    }

private:
    shared_ptr<mutex> plock;
};

以智能指针的方式去管理锁,能够实现在作用域外自动实现释放锁的操作,从而避免繁杂的在每处添加解锁操作的语句。因为是智能指针,所以可以保证这个解锁操作是一定能够发生的。

 

创建对象的时候,就自动进行上锁操作。同时,在对象消失的时候,我们定义了智能指针的删除器,即解锁操作!

 

完整的代码如下:

#include <iostream>
#include <mutex>
#include <memory>
using namespace std;

void Lock(mutex* mu){
    cout<<"lock"<<endl;
    mu->lock();
}

void unLock(mutex* mu)
{
    cout<<"unlock"<<endl;
    mu->unlock();
}

class Locks
{
public:
    Locks(mutex* mu):plock(mu,unLock){
        Lock(plock.get());
    }

private:
    shared_ptr<mutex> plock;
};

int main()
{
    mutex mu;
    try{
        Locks m(&mu);
        throw exception();
    }
    catch(exception &e){}

    system("pause");
    return 0;
}

最终的结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值