выход из потока, но по-прежнему удерживать мьютекс

Умер поток, содержащий мьютекс. Другой поток зайдет в тупик, когда вызовет «pthread_mutex_lock», хотя я использую атрибут «PTHREAD_MUTEX_ERRORCHECK».

#include <pthread.h>
#include <iostream>
#include <unistd.h>

using namespace std;

pthread_mutex_t mutex;

void *handler(void *)
{
    cout << "child thread" << endl;
    int ret = pthread_mutex_lock(&mutex);
    cout << "child ret: " << ret << endl;
    pthread_exit(NULL);
}

int main()
{
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);

    pthread_mutex_init(&mutex, &attr);
    pthread_mutexattr_destroy(&attr);

    pthread_t tid;
    pthread_create(&tid, NULL, handler, NULL);

    sleep(2);
    cout << "father awake" << endl;

    int ret = pthread_mutex_lock(&mutex);
    cout << "father ret: " << ret << endl;
    return 0;
}

Выход:

введите здесь описание изображения

[СРЕДА LINUX]: Linux ubuntu 3.19.0-25-generic # 26 ~ 14.04.1-Ubuntu SMP


person Pengcheng    schedule 03.12.2015    source источник
comment
Вы не задавали здесь никаких вопросов, но если ваш вопрос заключается в том, как справиться с этой проблемой, лучшим решением будет убедиться, что ваш поток освобождает все мьютексы, которые он может удерживать, перед выходом.   -  person Jeremy Friesner    schedule 03.12.2015
comment
Этот вопрос, похоже, спрашивает о результатах того, что делает ваш код.   -  person tijko    schedule 03.12.2015


Ответы (2)


Возможно, вы думаете об надежном атрибуте мьютексов (pthread_mutexattr_setrobust() ), а не мьютекса с типом проверки ошибок. Надежный мьютекс уведомил бы ваш основной поток о том, что держатель блокировки мьютекса завершился с помощью EOWNERDEAD.

Тип PTHREAD_MUTEX_ERRORCHECK, с другой стороны, просто :

  1. попытка рекурсивно заблокировать собственный заблокированный мьютекс (здесь не применимо)
  2. попытка разблокировать мьютекс, заблокированный другим потоком (здесь не применимо)
  3. попытка разблокировать разблокированный мьютекс (здесь не применимо)
person pilcrow    schedule 03.12.2015

Это небольшой пример использования вызова pthread_mutexattr_setrobust для настройки mutex, который никогда не разблокировался обратно в согласованное состояние:

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

pthread_mutex_t lock;

void dropped_thread(void)
{
    printf("Setting lock...\n");
    pthread_mutex_lock(&lock);
    printf("Lock set, now exiting without unlocking...\n");
    pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
    pthread_t lock_getter;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); 
    pthread_mutex_init(&lock, &attr);
    pthread_mutexattr_destroy(&attr);
    pthread_create(&lock_getter, NULL, (void *) dropped_thread, NULL);
    sleep(2);

    printf("Inside main\n");
    printf("Attempting to acquire unlocked mutex?\n");

    pthread_mutex_consistent(&lock);
    pthread_mutex_unlock(&lock);
    pthread_mutex_lock(&lock);

    printf("Successfully acquired lock!\n");
    pthread_mutex_destroy(&lock);
    return 0;
}

Как вы можете видеть, сделав вызов pthread_mutex_consistent после установки mutex надежность, его состояние снова помечается как стабильное.

person tijko    schedule 03.12.2015
comment
Вы забыли инициализировать мьютекс с помощью pthread_mutex_init. Без этого ваш код приведет к тупиковой ситуации. - person walkerlala; 07.08.2017