1

我正在尝试基于固定数组实现线程安全队列。队列包含一个 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它工作得很好。我认为这一定是某种僵局。有任何想法吗?队列的非线程安全版本已经过测试并且工作正常。为了清楚起见,代码被隐藏了。有任何想法吗?

4

3 回答 3

1

我相信问题出在queue_get. 您在互斥锁解锁之前返回。尝试将返回值存储到临时变量中,解锁互斥锁,然后返回值。

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;
}
于 2013-07-24T16:43:17.627 回答
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;
于 2013-07-24T16:44:28.637 回答
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);

请注意缺少所需的演员表)

于 2013-07-24T16:45:44.463 回答