Почему этот код не вызывает тупик? - PullRequest
1 голос
/ 06 мая 2020

У меня есть код ниже, в котором функциональная панель блокирует мьютекс, а затем вызывает функцию 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();
} 

Ответы [ 2 ]

2 голосов
/ 06 мая 2020

Спецификация потока POSIX позволяет реализации потока POSIX использовать любой из трех стандартных типов мьютекса в качестве значения по умолчанию:

Если тип мьютекса PTHREAD_MUTEX_DEFAULT, поведение из pthread_mutex_lock () может соответствовать одному из трех других стандартных типов мьютексов

Что такое PTHREAD_MUTEX_DEFAULT? Это примерно то, что вы ожидаете. :

Значение по умолчанию для атрибута type - PTHREAD_MUTEX_DEFAULT.

...

Реализация может сопоставьте PTHREAD_MUTEX_DEFAULT с одним из других типов мьютексов.

Вы ожидаете, что ваш мьютекс будет PTHREAD_MUTEX_NORMAL, что вызовет здесь взаимоблокировку. Однако ваша конкретная реализация потока выглядит как тип PTHREAD_MUTEX_RECURSIVE, который может быть заблокирован более одного раза одним и тем же процессом. Это то поведение, которое вы наблюдаете.

0 голосов
/ 06 мая 2020
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 завершится sh

...