嗨,我想问下列问题的最佳解决方案是什么。 (下面解释)
我有以下内存库代码(简化):
// struct is opaque to callee
struct memory {
void *ptr;
size_t size;
pthread_mutex_t mutex;
};
size_t memory_size(memory *self)
{
if (self == NULL) {
return 0;
}
{
size_t size = 0;
if (pthread_mutex_lock(self->mutex) == 0) {
size = self->size;
(void)pthread_mutex_unlock(self->mutex);
}
return size;
}
}
void *memory_beginAccess(memory *self)
{
if (self == NULL) {
return NULL;
}
if (pthread_mutex_lock(self->mutex) == 0) {
return self->ptr;
}
return NULL;
}
void memory_endAccess(memory *self)
{
if (self == NULL) {
return;
}
(void)pthread_mutex_unlock(self->mutex);
}
问题:
// ....
memory *target = memory_alloc(100);
// ....
{
void *ptr = memory_beginAccess(target);
// ^- implicit lock of internal mutex
operationThatNeedsSize(ptr, memory_size(target));
// ^- implicit lock of internal mutex causes a deadlock (with fastmutexes)
memory_endAccess(target);
// ^- implicit unlock of internal mutex (never reached)
}
所以,我想到了三种可能的解决方案:
1。)使用递归互斥锁。 (但我听说这是不好的做法,应该尽可能避免。)
2.)使用不同的函数名称或标志参数: memory_sizeLocked() memory_size()
memory_size(TRUE)memory_size(FALSE)
3.。)如果pthread_mutex_t返回EDEADLK并增加deadlock counter
(并在解锁时递减)(与递归互斥量相同?),则捕获。
那么这个问题有另一个解决方案吗?或者是以上三种解决方案之一"足够好" ?
感谢您提前提供任何帮助
答案 0 :(得分:0)
使用相同功能的两个版本,一个锁定,另一个不锁定。这样您就必须修改最少量的代码。它在逻辑上也是正确的,因为你必须知道你何时处于代码的关键部分。