【发布时间】:2014-05-24 14:57:27
【问题描述】:
嗨,我想问一下以下问题的最佳解决方案是什么。 (解释如下)
我有以下内存库代码(简化):
// 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(TRUE) memory_size(FALSE)
3.) 捕获 pthread_mutex_t 返回 EDEADLK 并增加 deadlock counter(解锁时减少)(与递归互斥锁相同?)
那么对于这个问题还有其他解决方案吗?还是上述三种解决方案之一“足够好”?
提前感谢您的帮助
【问题讨论】:
-
一定要使用同一个互斥体吗?
-
是的,因为内存操作(如重新分配)会影响大小。
-
问题是,我想要可以在没有对“beginAccess”的函数调用以及在“beginAccess”和“endAccess”块内(执行多个操作时)调用的函数。
标签: c multithreading thread-safety pthreads mutex