Проблема Android NDK проблема pthread_mutex_unlock - PullRequest
0 голосов
/ 22 сентября 2011

У меня проблема с pthread_mutex_unlock и родным приложением NDK для активности. Я добавил сообщения регистрации для каждой инициализации мьютекса, блокировки, успешной блокировки и разблокировки. Моя программа зашла в тупик, потому что разблокировка мьютекса говорит мне, что поток, пытающийся разблокировать мьютекс, не заблокировал его. Моя регистрация говорит иначе. Поэтому мне интересно, есть ли что-то, что я делаю / не делаю, что может быть причиной этого. Число в () - это mutex_t *, за которым следуют номер строки кода и идентификатор потока, возвращаемые функцией pthread_self (). Мне кажется, что поток 1584064 получил блокировку и выполняет ее обработку. Затем поток 1597448 пытается заблокировать и корректно приостанавливается в ожидании получения блокировки. Проблема в том, что 1584064 затем завершает свою работу и пытается снять блокировку. Pthread_mutex_unlock возвращает ошибку (1).

09-21 13: 55: 27.098: ПРЕДУПРЕЖДЕНИЕ / native-активность (1333): попытаться заблокировать мьютекс (2154220968) Линия: 3041 Резьба: 1584064

09-21 13: 55: 27.098: ПРЕДУПРЕЖДЕНИЕ / нативная активность (1333): Успех: заблокированный мьютекс (2154220968) Линия: 3041 Резьба: 1584064

09-21 13: 55: 31.668: DEBUG / dalvikvm (352): GC_EXPLICIT освобождено 8K, 4% бесплатно 8606K / 8963K, пауза 3 мс + 423 мс

09-21 13: 55: 31.898: ПРЕДУПРЕЖДЕНИЕ / нативная активность (1333): попытаться заблокировать мьютекс (2154220968) Линия: 3041 Резьба: 1597448

09-21 13: 55: 32.198: ПРЕДУПРЕЖДЕНИЕ / native-активность (1333): ошибка: 1 разблокировка Mutex (2154220968) Линия: 3045 Резьба: 1584064

Инициализация - это макрос, который выглядит следующим образом:

#define InitializeCriticalSection(p, X) \
{ \
LOGW("Initialize Mutex(%u)", p); \
*p = PTHREAD_MUTEX_INITIALIZER; \
pthread_mutexattr_t attr; \
pthread_mutexattr_init(&attr); \
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); \
int ii_p = pthread_mutex_init((pthread_mutex_t *)p, &attr); \
pthread_mutexattr_destroy(&attr); \
LOGW("Initialize Mutex(%u) Returned %d", (pthread_mutex_t *)p, ii_p); \
}

Один поток - это стандартный поток NDK, другой - мой собственный поток таймера, инициализированный так:

pthread_t thread;
pthread_attr_t pattr;
int state;
state = pthread_attr_init(&pattr);
 pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);

if (!state)
{
    LOGW("Creating Timers Thread %d MS", dwMsecs);
    int iRetTest = pthread_create(&thread, &pattr, TimersThread, (void *)pTimer);
    pthread_attr_destroy(&pattr);
}

и т. Д. ... обработка ошибок

Кажется, нет никакой разницы, присоединяю ли я к виртуальной машине ThreadchurthThread или нет в моем потоке таймеров. Кажется, что мьютексы не работают через потоки правильно. Заранее спасибо за любую помощь, которую вы можете предоставить.

1 Ответ

1 голос
/ 22 сентября 2011

Я понял это.Проблема была в инициализации.Хотя это работает на нескольких других платформах, я действительно делал это неправильно.Если вы используете пользовательский init, вы должны установить новый мьютекс).Новый init выглядит так:

#define InitializeCriticalSection(p) \
{ \
p = new pthread_mutex_t; \
LOGW("Initialize Mutex(%u)", p); \
pthread_mutexattr_t attr; \
pthread_mutexattr_init(&attr); \
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); \
int ii_p = pthread_mutex_init(p, &attr); \
pthread_mutexattr_destroy(&attr); \
LOGW("Initialize Mutex(%u) Returned %d", p, ii_p); \
}

Вот так!

...