我正在尝试实现一个基于固定数组的线程安全队列。该队列包含一个空指针数组。
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;
}
我认为这是一种非常直接的方法。不幸的是,程序卡住了。但是,当我删除 func_b
中的 queue_get(q);
时,它工作得很好。我认为这一定是某种僵局。有任何想法吗? Queue 的非线程安全版本已经过测试并且工作正常。为了清楚起见,代码被隐藏了。有什么想法吗?
最佳答案
您需要将 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;
(从更文体的角度来看:这样你的值(value)分配会更“干净”:
int * ptr1 = malloc(sizeof(*ptr1));
*ptr1 = 5;
queue_put(q, ptr1);
注意缺少强制转换)
关于c - 使用 pThreads : Deadlock? 实现线程安全队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17839930/