Заблокируйте взаимное исключение многократно в том же потоке

Я разрабатываю приложение на встроенном Linux ОС (uClinux), и я должен смочь заблокировать взаимное исключение несколько раз (тем же потоком).

У меня есть взаимное исключение и mutexattr, определенный и инициализированный следующим образом:

pthread_mutexattr_t waiting_barcode_mutexattr;
pthread_mutex_t waiting_barcode_mutex;

pthread_mutexattr_init(&waiting_barcode_mutexattr);
pthread_mutexattr_settype(&waiting_barcode_mutexattr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&waiting_barcode_mutex, &waiting_barcode_mutexattr);

Но когда я пытаюсь получить блокировку дважды, она блокируется на второй блокировке:

pthread_mutex_lock(&waiting_barcode_mutex);
pthread_mutex_lock(&waiting_barcode_mutex);

Я инициализирую его неправильно или являюсь там лучшим способом выполнить то же?

Заранее спасибо.

Заключения:

  • По-видимому, PTHREAD_MUTEX_RECURSIVE или PTHREAD_MUTEX_RECURSIVE_NP не работают так, я не могу создать повторно используемое взаимное исключение.
  • try_lock является отрицательным результатом также. Это получает блокировку, если это может и возвращать ошибку, если это не может получить блокировку. К сожалению, ошибка просто сообщает мне, что взаимное исключение уже используется, и я не могу узнать, владеет ли текущий поток уже блокировкой или нет.
  • pthread_mutex_lock может возвратить ошибку, если текущий поток имеет блокировку, но для этого я должен создать взаимное исключение типа PTHREAD_MUTEX_ERRORCHECK, и я не могу создать один также.
10
задан Megacan 13 May 2010 в 13:51
поделиться

2 ответа

Похоже, мьютекс pthread не реентерабелен. Вы можете обойти это с помощью флага, указывающего, что ваш поток уже заблокировал мьютекс:

bool haveLock = false;// thread variable
pthread_mutex_t waiting_barcode_mutex; // also thread var

mylock()
{
   if( haveLock ) return; // no need to lock twice
   pthread_mutex_lock(&waiting_barcode_mutex);
   haveLock = true;
}

myunlock()
{
   haveLock = false;
   pthread_mutex_unlock(&waiting_barcode_mutex); // or whatever the unlock call is
}
2
ответ дан 3 December 2019 в 22:35
поделиться

Разве это не то, что вы ожидали?

Первый вызов устанавливает блокировку, а второй вызов блокирует, пока первая блокировка не будет снята ( pthread_mutex_unlock ). Вот что делают замки.

Из документации:

«Если мьютекс уже заблокирован, вызывающий поток блокируется, пока мьютекс не станет доступен."

Возможно, вам нужен pthread_mutex_trylock ? Трудно сказать, если мы не знаем, чего вы пытаетесь достичь.

ИСПРАВЛЕНИЕ:

Я не видел, что вы устанавливали PTHREAD_MUTEX_RECURSIVE ... . Дайте мне подумать об этом еще.

ПОСЛЕ ДУМА:

Судя по поиску кода в Google, похоже, что PTHREAD_MUTEX_RECURSIVE реализован не во всех библиотеках. Вы можете попробовать PTHREAD_MUTEX_RECURSIVE_NP, или вы можете сделать что-нибудь необычное, чтобы обойти это.

10
ответ дан 3 December 2019 в 22:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: