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

关于PTHREAD_MUTEX_RECURSIVE的问题:被其他线程锁定时发生阻塞

关于PTHREAD_MUTEX_RECURSIVE阻塞问题的解析与解决

嘿,我来帮你捋清楚这个问题!首先得纠正一个很容易踩的误区:递归互斥锁(PTHREAD_MUTEX_RECURSIVE)并不是让多个线程都能随便加锁的“万能锁”——它的核心作用只是允许同一个线程对同一把锁多次加锁而不会死锁,但不同线程之间的互斥性和普通锁完全一样。所以当其他线程已经持有这把锁时,你的线程尝试加锁被阻塞是完全正常的行为,这不是bug,是递归锁的设计本意。

再看你贴的代码片段,main函数里的pthread_mutexat...明显没写完,大概率是漏掉了设置锁类型的关键步骤?如果没把锁属性设置为递归类型,那你的锁本质还是普通的互斥锁,连同一线程多次加锁都会死锁,更别说线程间的情况了。

补全正确的递归锁使用代码

下面是完整的可运行示例,你可以看看递归锁的正确用法,以及线程间互斥的正常表现:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t m;
pthread_mutexattr_t ma;

void* exec_th(void* arg) {
    printf("THREAD %p 准备加锁\n", pthread_self());
    // 其他线程持有锁时,这里会阻塞——不管是不是递归锁
    pthread_mutex_lock(&m);
    printf("THREAD %p 第一次加锁成功\n", pthread_self());
    
    // 递归锁的核心特性:同一线程可以再次加锁,不会死锁
    pthread_mutex_lock(&m);
    printf("THREAD %p 第二次加锁成功(递归锁生效)\n", pthread_self());
    
    // 划重点:加了几次锁就要解锁几次,少一次都不行!
    pthread_mutex_unlock(&m);
    pthread_mutex_unlock(&m);
    
    printf("THREAD %p 解锁完成\n", pthread_self());
    return (void*)0;
}

int main() {
    // 初始化锁属性
    pthread_mutexattr_init(&ma);
    // 必须设置为递归锁类型,这一步千万别忘!
    pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
    // 用属性初始化互斥锁
    pthread_mutex_init(&m, &ma);
    
    pthread_t th1, th2;
    pthread_create(&th1, NULL, exec_th, NULL);
    // 先让th1拿到锁,再启动th2,就能看到th2被阻塞的过程
    sleep(1);
    pthread_create(&th2, NULL, exec_th, NULL);
    
    pthread_join(th1, NULL);
    pthread_join(th2, NULL);
    
    // 清理资源
    pthread_mutex_destroy(&m);
    pthread_mutexattr_destroy(&ma);
    return 0;
}

几个必须记住的关键点

  • 递归锁不打破线程间互斥:它只解决同一线程多次加锁的死锁问题,不同线程之间该阻塞还是会阻塞,这是正常的同步逻辑。
  • 一定要正确初始化属性:如果没调用pthread_mutexattr_settype设置PTHREAD_MUTEX_RECURSIVE,你的锁就是默认的普通锁,同一线程多次加锁直接死锁。
  • 解锁次数要和加锁次数匹配:递归锁被加了N次,就必须解锁N次,否则其他线程永远拿不到锁。

如果你的需求是让多个线程同时访问某个资源,那递归锁根本不是正确的选择,你应该考虑读写锁(pthread_rwlock_t)或者其他适合并发访问的同步机制哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:26:22