死锁:解决方案(1)

死锁问题的原因是资源的相互等待,这里所说的资源通常是指锁(当然也可以是其它资源),导致两个线程都无法继续,因为每个线程都在等着对方释放资源。以下提出几种避免死锁的方案

方案1:如果在某次操作时,需要锁住两个互斥元,那么这两个互斥元要么同时锁住,要么一个都不锁. 考虑这样一种场景:需要将两个数据做一下交换,在交换时,这两个数据需要被锁住。那么在交换的代码里面同时锁住这两个数据,代码如下所示:

class some_big_object;

void swap(some_big_object& lhs, some_big_object& rhs);

class X
{
private:
    some_big_object some_detail;
    std::mutex m;
public:
    X(some_big_object const& sd) : some_detail(ds) {}
    friend void swap(X& lhs, X& rhs)
    {
        if(&lhs == & rhs) return ;
        std::lock(lhs.m, rhs.m); //同时锁住两个互斥元
        std::lock_guard<std::mutex> lock_a(lhs.m, std::adopt_lock); //沿用锁的所有权,而不是再锁一次
	    std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock);//同上
        swap(lhs.some_detail, rhs.come_detail);
    } 
};

方案2:避免嵌套锁,如果你已经持有一个锁,就别再获取锁。如果确实是需要多个锁,那么可以像方案1一样,同时获得两个锁。

方案3:在持有锁时,避免调用用户提供的代码。这条准则其时是方案2的延续。因为你调用用户提供的代码(或者第三方接口)时,你不知道它会做什么,它可能包括获取锁在内的任何事情。如果正好它会获取锁,那么就锁就形成了嵌套,可能导致死锁。

方案四:以固定顺序获取锁。如果你确定需要获取多个锁,并且是逐个获取而非一次性获取,那么推荐的做法是以固定顺序获取锁。比如A,B,C三个互斥元,如果每次都以A->B->C的顺序获取锁,那么是不会死锁的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一条叫做nemo的鱼

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值