Android NDK problem pthread_mutex_unlock issue

2019-08-30 00:40发布

问题:

I'm having an issue with pthread_mutex_unlock and my native activity NDK app. I've added logging messages to each mutex initialization, lock, lock success and unlock. My program is getting deadlocked because the mutex unlock is telling me that the thread trying to unlock the mutex did not lock it. My logging says otherwise. So I'm wondering if there is something I'm doing / not doing that could be causing this. The number in () is the mutex_t* followed by the code line number and thread id returned by pthread_self(). To me it looks as though thread 1584064 has acquired the lock and is doing its processing. Then thread 1597448 attempts to lock and correctly is paused waiting to acquire the lock. The problem is when 1584064 then completes its work and tries to release the lock pthread_mutex_unlock returns an error (1).

09-21 13:55:27.098: WARN/native-activity(1333): Try to lock mutex (2154220968) Line:3041 Thread:1584064

09-21 13:55:27.098: WARN/native-activity(1333): Success: Locked Mutex (2154220968) Line:3041 Thread:1584064

09-21 13:55:31.668: DEBUG/dalvikvm(352): GC_EXPLICIT freed 8K, 4% free 8606K/8963K, paused 3ms+423ms

09-21 13:55:31.898: WARN/native-activity(1333): Try to lock mutex (2154220968) Line:3041 Thread:1597448

09-21 13:55:32.198: WARN/native-activity(1333): Error:1 Unlocking Mutex(2154220968) Line:3045 Thread:1584064

Initialization is a macro that looks like this:

#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); \
}

One thread is the standard NDK thread, the other one is my own timer thread initialized like this:

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);
}

etc... error handling

It doesn't seem to make any difference if I AttachCurrentThread to the vm or not in my timers thread. It seems like mutexes are not working across threads correctly. THanks in advance for any help you can provide.

回答1:

I figured it out. The problem was in the initialization. Although this works on several other platforms, I really wasn't doing it right. If you use custom init you should new the mutex). New init looks like this:

#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); \
}

Whew!