ミューテックスを使用して自分で再帰的なミューテックス型を作成できるかどうか疑問に思っていましたがPTHREAD_MUTEX_ERRORCHECK
、これが結果です。
typedef struct {
pthread_mutex_t mutex;
uint32_t deadlocks;
pthread_t owner;
BOOL isLocked;
} pthread_recursivemutex_t;
int pthread_recursivemutex_init(pthread_recursivemutex_t *mutex)
{
int ret;
pthread_mutexattr_t attr;
mutex->deadlocks = 0;
ret = pthread_mutexattr_init(&attr);
if (ret != 0) {
return ret;
}
(void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
ret = pthread_mutex_init(&mutex->mutex, &attr);
(void)pthread_mutexattr_destroy(&attr);
mutex->isLocked = FALSE;
return ret;
}
void pthread_recursivemutex_lock(pthread_recursivemutex_t *mutex)
{
int ret;
BOOL locked;
locked = mutex->isLocked;
__sync_synchronize();
if (locked == TRUE) {
if (pthread_equal(pthread_self(), mutex->owner) == 0) {
return;
}
}
ret = pthread_mutex_lock(&mutex->mutex);
if (ret == 0) {
mutex->deadlocks = 0;
__sync_synchronize();
mutex->isLocked = TRUE;
} else if (ret == EDEADLK) {
mutex->deadlocks += 1;
}
}
void pthread_recursivemutex_unlock(pthread_recursivemutex_t *mutex)
{
if (mutex->deadlocks == 0) {
(void)pthread_mutex_unlock(&mutex->mutex);
__sync_synchronize();
mutex->isLocked = FALSE;
} else {
mutex->deadlocks -= 1;
}
}
void pthread_recursivemutex_destroy(pthread_recursivemutex_t *mutex)
{
(void)pthread_mutex_destroy(&mutex->mutex);
}
PTHREAD_MUTEX_RECURSIVE
このタイプの再帰的ミューテックスは、次の属性を持つミューテックスよりもはるかに高速であることがわかりました。
iterations : 1000000
pthread_mutex_t : 71757 μSeconds
pthread_recursivemutex_t : 48583 μSeconds
テストコード (それぞれ 1000000 回呼び出されます):
void mutex_test()
{
pthread_mutex_lock(&recursiveMutex);
pthread_mutex_lock(&recursiveMutex);
pthread_mutex_unlock(&recursiveMutex);
pthread_mutex_unlock(&recursiveMutex);
}
void recursivemutex_test()
{
pthread_recursivemutex_lock(&myMutex);
pthread_recursivemutex_lock(&myMutex);
pthread_recursivemutex_unlock(&myMutex);
pthread_recursivemutex_unlock(&myMutex);
}
pthread_recursivemutex_t
pthread_mutex_t
?!のほぼ 2 倍の速さです。しかし、どちらも同じように振る舞う...?
上記の解決策は安全ですか?