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

Ubuntu20.04下pthread_rwlock先解锁后加写锁导致阻塞问题求助

Ubuntu 20.04下pthread_rwlock异常行为解析:非法解锁导致的阻塞差异

问题现象

在Ubuntu 20.04系统中,同一线程内操作pthread_rwlock时,两种非法解锁场景出现了不同的阻塞表现:

  1. 场景一:初始化后直接解锁,后续加写锁无限阻塞
#include <stdio.h> 
#include <pthread.h> 
pthread_rwlock_t rwlock;
int main() {

    pthread_rwlock_init(&rwlock, NULL);

    pthread_rwlock_unlock(&rwlock);
    pthread_rwlock_wrlock(&rwlock);  // 无限阻塞
}
  1. 场景二:加锁后多次解锁,后续加写锁不阻塞
#include <stdio.h> 
#include <pthread.h> 
pthread_rwlock_t rwlock;
int main() {

    pthread_rwlock_init(&rwlock, NULL);
    pthread_rwlock_wrlock(&rwlock);
    pthread_rwlock_unlock(&rwlock);
    pthread_rwlock_unlock(&rwlock);
    pthread_rwlock_wrlock(&rwlock);  // 即使解锁两次也不阻塞
}

原因解析

这两种表现都是未定义行为的产物,pthread_rwlock的API有明确规范:

  • 只有持有锁的线程才能调用pthread_rwlock_unlock
  • 解锁次数必须与加锁次数严格匹配

具体到两个场景:

  • 场景一:初始化后的读写锁处于未被任何线程持有的状态,此时调用unlock会破坏锁的内部计数(通常会将可用计数变为负数)。后续调用wrlock时,锁的内部状态已异常,线程尝试获取锁时会陷入无限等待。
  • 场景二:第一次unlock是合法操作,将锁释放回可用状态;第二次unlock属于非法操作,会让锁的内部可用计数变为大于1的数值。后续调用wrlock时,由于内部计数仍大于0,线程可以直接获取锁,因此不会阻塞。

注意事项

无论哪种场景,非法调用pthread_rwlock_unlock都是严重错误,绝对不能依赖这种未定义行为的表现。正确做法是严格遵循锁的使用规范:只有持有锁的线程才能解锁,且解锁次数与加锁次数完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:40:33