我正在尝试基于固定数组实现线程安全队列。该队列包含一个void指针数组。
pthread_t a;
pthread_t b;
Queue *q;
Queue* queue_new(int size)
{
// malloc stuff
}
void queue_put(Queue* q, void* item)
{
pthread_mutex_lock(&(q->lock));
// details on array queue managment
pthread_mutex_unlock(&(q->lock));
}
void* queue_get(Queue* q)
{
pthread_mutex_lock(&(q->lock));
// more details ...
return q->queue[old_front];
pthread_mutex_unlock(&(q->lock));
}
void *func_a (void *ptr)
{
void *ptr1 = malloc(sizeof(int));
*((int*)ptr1) = 5;
queue_put(q, ptr1);
void *ptr2 = malloc(sizeof(int));
*((int*)ptr2) = 4;
queue_put(q, ptr2);
return NULL;
}
void *func_b (void *ptr)
{
void *ptr3 = malloc(sizeof(int));
*((int*)ptr3) = 7;
queue_put(q, ptr3);
queue_get(q); // critical part !
return NULL;
}
int main ()
{
q = queue_new(3);
pthread_create(&a, NULL, func_a, NULL);
pthread_create(&b, NULL, func_b, NULL);
pthread_join(a, NULL);
pthread_join(b, NULL);
queue_print(q);
return 0;
}
我认为这是一种非常简单的方法。不幸的是,程序冻结了。但是,当我删除queue_get(q);
中的func_b
时,它的工作正常。我认为这必定是某种僵局。有任何想法吗? Queue的非线程安全版本已经过测试,工作正常。为清晰起见,隐藏了代码。有什么想法吗?
答案 0 :(得分:1)
我认为问题出在queue_get
之内。您在互斥锁解锁之前返回。尝试将返回值存储到一个temprary变量中,解锁互斥锁,然后返回值。
void* queue_get(Queue* q)
{
void* temp;
pthread_mutex_lock(&(q->lock));
// more details ...
temp = q->queue[old_front];
pthread_mutex_unlock(&(q->lock));
return temp;
}
答案 1 :(得分:1)
在解锁queue_get中的互斥锁之前,您正在返回:
return q->queue[old_front];
pthread_mutex_unlock(&(q->lock));
这应该是:
void *retValue = q->queue[old_front];
pthread_mutex_unlock(&(q->lock));
return retValue;
答案 2 :(得分:1)
您希望将queue_get
中的解锁线移到return
之上,因为现在它永远不会到达。所以锁从未被释放。
pthread_mutex_unlock(&(q->lock));
return q->queue[old_front];
或者,你可能想要什么,以避免在锁外触摸它:
void * ret = q->queue[old_front];
pthread_mutex_unlock(&(q->lock));
return ret;
(从更具风格的观点来看:你的价值分配会更加“清洁”:
int * ptr1 = malloc(sizeof(*ptr1));
*ptr1 = 5;
queue_put(q, ptr1);
注意缺少演员阵容)