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

C语言pthread多线程同时锁定同一互斥锁的修复方案咨询

问题根源分析

嘿,我一眼就揪出问题所在了——这根本不是递归互斥锁的锅,而是你踩了C语言值传递的经典陷阱!你的twoSectionRoute函数接收的firstSection和secondSection是按值传递的pthread_mutex_t变量,这意味着每个线程调用这个函数时,都会拿到一份互斥锁的副本。你在函数里调用pthread_mutex_trylock(&firstSection)时,操作的只是这个副本,完全没碰你定义的那个全局互斥锁实例!

这就导致两个线程各自在自己的副本上成功加锁,看起来像是“同时锁定了同一个互斥锁”,但实际上它们对真实的全局互斥锁没做任何有效操作,自然不会产生互斥效果。

修复方案

要解决这个问题,核心是让所有线程操作同一个互斥锁实例,具体修改如下:

步骤1:把函数参数改成指针类型

将函数的参数从pthread_mutex_t改为pthread_mutex_t*,这样传递的是互斥锁的地址,所有线程操作的都是同一个全局实例:

void twoSectionRoute(pthread_mutex_t *firstSection, pthread_mutex_t *secondSection){
    bool pathClear = false;
    while (!pathClear){
        pthread_mutex_lock(&intersection);
        if (pthread_mutex_trylock(firstSection) == 0){  // 直接用指针,无需取地址
            if (pthread_mutex_trylock(secondSection) == 0){
                pathClear = true;
                pthread_mutex_unlock(&intersection);
            } else {
                pthread_mutex_unlock(firstSection);
                pthread_mutex_unlock(&intersection);
                sleep(2);
            }
        } else {
            pthread_mutex_unlock(&intersection);
            sleep(2);
        }
    }
    safeUnlockTwoMutexes(firstSection, secondSection, 1);  // 这里的参数也要同步改指针
}

步骤2:同步修改safeUnlockTwoMutexes函数

你必须把safeUnlockTwoMutexes的参数也改成pthread_mutex_t*,否则它解锁的还是副本,会导致真实的互斥锁永远处于锁定状态。修改后的函数示例:

void safeUnlockTwoMutexes(pthread_mutex_t *first, pthread_mutex_t *second, int flag){
    // 直接用指针执行解锁操作
    pthread_mutex_unlock(first);
    pthread_mutex_unlock(second);
    // 其他业务逻辑...
}

步骤3:调用函数时传递互斥锁地址

线程调用twoSectionRoute时,要传入全局互斥锁的地址,比如:

// 你的全局互斥锁定义(假设在文件开头)
pthread_mutex_t firstSection = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t secondSection = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t intersection = PTHREAD_MUTEX_INITIALIZER;

// 线程函数内的调用代码
twoSectionRoute(&firstSection, &secondSection);
额外小提示
  1. 你用intersection主锁保护互斥锁状态检查的思路是对的,能避免死锁,而且当前代码里的解锁顺序(先释放已拿到的局部锁,再释放主锁)也没问题,继续保持就好。
  2. 固定sleep(2)重试的方式比较简单,但如果对性能有要求,可以考虑用条件变量来实现更高效的唤醒机制,不过低并发场景下当前方式完全够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:47:33