C++并发与多线程编程--互斥量用法


1、互斥量概念

互斥量是个类对象。
理解成一把锁,多个线程尝试使用lock()成员函数来加锁,只有一个线程能锁定成功。
如果没有锁定成功,那么流程卡在lock()这里不断的尝试去锁住这把锁头。

互斥量使用要小心,保护数据不多也不少,少了,没达到保护的效果,多了,影响效率。


2、互斥量用法

(1)lock(),unlock()

lock() 和unlock()要成对使用,有lock(),必然有unlock()。
不应该也不允许调用了一次lock(),却调用多次unlock()。

std::mutex my_mutex;
//.........

my_mutex.lock();

//...............

my_mutex.unlock();

为了防止大家忘记unlock(),引入了一个 stdlock_guard() 类的模板。


(2)std::lock_guard()

使用std::lock_guard(),直接取代lock()和unlock(), 可以解决忘记上述(1)法忘记使用unlock()造成的问题。
使用lock_guard之后,再不能使用lock() 和unlock()。

std::mutex my_mutex;
//...............
std::lock_guard(std::mutex) sbguard(my_mutex);


3、死锁原因及解决方法

(1)造成死锁的原因

死锁至少两个互斥量才能产生。

如:现有金锁、银锁
两个线程A、B
(1)线程A执行的时候,这个线程先锁金锁,把金锁lock()成功后,然后锁银锁;
//出现上下文切换
(2)线程B执行了,这个线程先锁银锁,因为银锁还没被锁,所以银锁lock成功,线程B要去lock金锁…
//这样死锁就产生了。
(3)线程A因为拿不到银锁头,流程走不下去。
(4)线程B因为拿不到金锁头,流程走不下去。


(2)死锁的一般解决方法

只要保证这两个互斥量的顺序一致就不会死锁。


(3)std::lock()函数模板:用来处理多个互斥量

能力:一次锁住两个或者两个以上的互斥量(至少两个)。

它不存在因为在多个线程中,因为锁的顺序问题导致死锁的风险。
std::lock():如果互斥量有一个没锁住,它就在那里等着,等所有的互斥量都锁住,它才能继续往下走(返回);
要么两个互斥量都锁住,两个互斥量都没锁住。如果只锁了一个,另外一个没锁成功,则它立即把已经锁住的解锁。

std::lock(my_mutex1, my_mutex2);
//.............
my_mutex1.unlock();
my_mutex2.unlock();


(4)std::lock_guard()的参数std::adopt_lock函数

std::lock(my_mutex1, my_mutex2);

//前面已经lock该互斥量,这里工作仅是在析构函数中会调用该互斥量的unlock
std::lock_guard(std::mutex) sbguard(my_mutex1,std::adopt_lock);  
std::lock_guard(std::mutex) sbguard(my_mutex2,std::adopt_lock);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值