c - 使用 pThreads : Deadlock? 实现线程安全队列

标签 c thread-safety pthreads deadlock

我正在尝试实现一个基于固定数组的线程安全队列。该队列包含一个空指针数组。

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/

相关文章:

java - 如何检测虚假唤醒

将文本文件中的单词大写

C 程序不给出素数

c - 删除 skb 或扩展传出 skb

swift - 更新从后台线程更改 UI 的变量 - SWIFTUI

pthreads - 线程 : one printf statement get printed twice in child thread

c - pthread_exit 和/或 pthread_join 导致中止和 SegFaults

c - 在 C 中使用 const struct 而不是定义分组配置参数有效吗?

java - java中如何实现线程同步而不影响效率

python - asyncio 的 loop.run_in_executor 是线程安全的吗?