Я разрабатываю приложение на встроенном 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 не реентерабелен. Вы можете обойти это с помощью флага, указывающего, что ваш поток уже заблокировал мьютекс:
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 }
Разве это не то, что вы ожидали?
Первый вызов устанавливает блокировку, а второй вызов блокирует, пока первая блокировка не будет снята ( pthread_mutex_unlock
). Вот что делают замки.
Из документации:
«Если мьютекс уже заблокирован, вызывающий поток блокируется, пока мьютекс не станет доступен."
Возможно, вам нужен pthread_mutex_trylock
? Трудно сказать, если мы не знаем, чего вы пытаетесь достичь.
ИСПРАВЛЕНИЕ:
Я не видел, что вы устанавливали PTHREAD_MUTEX_RECURSIVE ... . Дайте мне подумать об этом еще.
ПОСЛЕ ДУМА:
Судя по поиску кода в Google, похоже, что PTHREAD_MUTEX_RECURSIVE реализован не во всех библиотеках. Вы можете попробовать PTHREAD_MUTEX_RECURSIVE_NP, или вы можете сделать что-нибудь необычное, чтобы обойти это.