【问题标题】:Why does this code not cause a dead-lock?为什么这段代码不会导致死锁?
【发布时间】:2020-08-20 21:26:48
【问题描述】:

我有下面的代码,其中函数 bar 锁定了互斥体,然后调用了函数 foo,但是函数 foo 锁定了同一个互斥体。根据我的理解,会发生死锁,因为 foo 试图锁定同一个互斥体并且它已被锁定在函数栏中。但下面的代码执行没有任何停止。谁知道原因??

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void foo()  
{  
    pthread_mutex_lock(&mutex);  
    cout<<"excuting foo!!"<<endl;
    pthread_mutex_unlock(&mutex);  
}  

void bar()  
{  
    pthread_mutex_lock(&mutex);  
    cout<<"excuting bar!!"<<endl;
    foo();  
    pthread_mutex_unlock(&mutex);  
}


int main()
{
    bar();
} 

【问题讨论】:

  • 我的死锁。我建议填写minimal reproducible example,以防我在填空时不小心修复了“错误”。
  • 您也没有检查 pthread_mutex_lock 的返回值。如果你的系统支持一些基本的死锁检测,它可能只是返回一个错误。

标签: c++ mutex deadlock


【解决方案1】:

POSIX thread specification 允许 POSIX 线程实现使用标准的三种互斥锁类型中的任何一种作为默认类型:

如果互斥锁类型是 PTHREAD_MUTEX_DEFAULT,则 pthread_mutex_lock() 可能对应于其他三个标准之一 互斥体类型

PTHREAD_MUTEX_DEFAULT 是什么?那是pretty much what you expect:

type属性的默认值为PTHREAD_MUTEX_DEFAULT。

...

一个实现可以将 PTHREAD_MUTEX_DEFAULT 映射到另一个 互斥体类型。

您希望您的互斥锁为PTHREAD_MUTEX_NORMAL,这将导致此处出现死锁。但是,您的特定线程实现似乎是 PTHREAD_MUTEX_RECURSIVE 类型,同一进程可以多次锁定它。这是您正在观察的行为。

【讨论】:

    【解决方案2】:
    You need to modify bar() as: 
    void bar()  
    {  
           pthread_mutex_lock(&mutex);  
            cout<<"excuting bar!!"<<endl;
            pthread_mutex_unlock(&mutex); 
            foo();  
    
    }
    

    在您的代码中,存在死锁,因为顺序如下 1. bar() 锁定互斥锁, 2. Foo() 试图再次锁定已被 bar 锁定的互斥锁 3. bar() 将其解锁,但较早的操作步骤 2,仍在等待互斥锁。此步骤等待第 2 步完成

    【讨论】:

    • 问题是为什么这段代码对于 OP 来说是死锁的。
    猜你喜欢
    • 2012-08-27
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多