关于C++11 mutex的死锁

slwj 2019-03-17 10:48:56
各位好,网上阅读一篇文章,有如下一段话:

std::mutex 的成员函数
构造函数,std::mutex不允许拷贝构造,也不允许 move 拷贝,最初产生的 mutex 对象是处于 unlocked 状态的。
lock(),调用线程将锁住该互斥量。线程调用该函数会发生下面 3 种情况:
(1). 如果该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用 unlock之前,该线程一直拥有该锁。
(2). 如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住。
(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。

,对其中的第三条
(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。

不是完全理解,它和第一种情况感觉没什么区别
如果该互斥量当前没有被锁住,则调用线程将该互斥量锁住,直到调用 unlock之前,该线程一直拥有该锁。

mutex被当前线程调用lock()锁住之后,怎么会产生死锁呢

多谢!
...全文
512 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
@风轻云淡_ 2019-03-17
  • 打赏
  • 举报
回复
(2). 如果当前互斥量被其他线程锁住,则当前的调用线程被阻塞住。
(3). 如果当前互斥量被当前调用线程锁住,则会产生死锁(deadlock)。

这两个连起来看就好解释了。一个互斥量被锁住的时候,另一个线程只能被阻塞,等待别的线程释放之后才能在锁住。举个例子:线程好比是水,互斥量好比是水桶,每一个线程用水加满水桶,执行完任务之后再负责把水倒掉;水桶里有水的情况下,其他线程想用,只能等着。现在出现了一个这样的线程,它自己加满的水,出于某些原因在水没倒掉的情况下,它又想用这个桶装新的一种水,就形成了它自己等待自己的情况,也就形成了所谓的死锁。
岚天逸剑 2019-03-17
  • 打赏
  • 举报
回复
如果同一线程重复调用同一个std::mutex,中间没有unlock,就会死锁,原因是std::mutex不是递归锁,换成递归锁std::recursive_mutex就可。
void mythread::dealock() {
    std::mutex g_pages_mutex;
    std::lock_guard<std::mutex> guard(g_pages_mutex);
    std::lock_guard<std::mutex> guard(g_pages_mutex); // 这里死锁
}

void mythread::nondealock() {
    std::mutex g_pages_mutex;
    std::lock_guard<std::recursive_mutex> guard(g_pages_mutex);
    std::lock_guard<std::recursive_mutex> guard(g_pages_mutex); // 这里不会死锁
}
WNs_ACE 2019-03-17
  • 打赏
  • 举报
回复 1
其实很简单,我举个例子你就明白了。


#include <iostream>
#include <mutex>

class myTestMutex
{
public:
myTestMutex(int m_m) : m(m_m) {}

~myTestMutex() {}

void Add(int number)
{
m_mutex.lock();
m += number;
m_mutex.unlock();
}

void PlusOne()
{
m_mutex.lock();
Add(1);
m_mutex.unlock();
}

private:
std::mutex m_mutex;
int m;
};
int main()
{
myTestMutex test(0);
//调用Add方法是没有问题的,而且有原子操作的效果。
test.Add(10);
//但是一定调用PlusOne方法就出现问题了,因为进入PlusOne方法的时候会调用m_mutex.lock()方法,
//还没有调用m_mutex.unlock()方法就马上进入Add方法了,然后Add方法马上又调用了m_mutex.lock(),
//然后m_mutex.lock()因为前面在PlusOne方法调用m_mutex.lock()方法,所以就出现阻塞,然后在Add方法就走不下去了,
//然后因为PlusOne方法调用了Add方法,所以导致PlusOne方法也走不下去了,出现死锁了。
test.PlusOne();
}

虽然c++11有递归互斥量来解决上面代码中的问题,但是这个递归互斥量会比较消耗资源,所以建议尽量在设计代码的时候处理掉这些问题

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧