You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pthread_cond_wait与互斥锁的死锁疑问:双线程数据处理场景

双线程数据同步的死锁疑问解答

问题描述

我需要开发一个双线程应用,一个线程负责准备数据,另一个线程负责处理数据。当没有数据可处理时,处理线程应进入休眠状态。我按照大量教程的示例编写了如下代码:

pthread_mutex_t mtx;
pthread_cond_t cond;

char *shared_data = NULL;

char *process_data() {
    char *dt;

    pthread_mutex_lock(&mtx);
    if(!shared_data) pthread_cond_wait(&cond, &mtx);

    dt = strdup(shared_data);
    free(shared_data);
    shared_data = NULL;

    pthread_mutex_unlock(&mtx);

    return dt;
}

void create_data(char *dt) {
    pthread_mutex_lock(&mtx);

    shared_data = strdup(dt);

    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mtx);
}

假设处理线程先启动:

  1. 此时shared_data为NULL,无数据可读,处理线程锁定互斥锁后等待cond触发;
  2. 数据准备线程启动后尝试锁定互斥锁,但该互斥锁已被处于等待状态的处理线程持有……

这难道不会造成死锁吗?我忽略了什么要点?


解答

不会产生死锁,你忽略了pthread_cond_wait的核心机制:当线程调用pthread_cond_wait时,会自动释放持有的互斥锁,进入条件等待状态;一旦被条件变量唤醒,线程会重新获取该互斥锁,之后才会继续执行后续代码。

对应你的场景流程:

  • 处理线程先启动,成功锁定mtx后,发现shared_data为空,调用pthread_cond_wait。此时处理线程会主动释放mtx,然后进入休眠,等待条件信号。
  • 数据准备线程此时可以正常锁定mtx,完成shared_data的赋值操作,接着调用pthread_cond_signal唤醒等待中的处理线程,最后释放mtx。
  • 被唤醒的处理线程会重新尝试获取mtx,拿到锁后继续执行数据复制、清理逻辑,完成后释放mtx。

额外注意事项

  1. 必须用while循环替代if判断:系统可能出现虚假唤醒(线程未收到signal/broadcast就被唤醒),用while循环可以重新检查条件,确保逻辑正确:
    // 替换原代码中的if判断
    while(!shared_data) pthread_cond_wait(&cond, &mtx);
    
  2. 初始化与销毁:使用前必须调用pthread_mutex_init和pthread_cond_init完成互斥锁和条件变量的初始化,使用结束后调用pthread_mutex_destroy和pthread_cond_destroy进行销毁,避免未定义行为。

内容的提问来源于stack exchange,提问作者White Owl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 23:32:46