Ubuntu20.04下pthread_rwlock先解锁后加写锁导致阻塞问题求助
Ubuntu 20.04下pthread_rwlock异常行为解析:非法解锁导致的阻塞差异
问题现象
在Ubuntu 20.04系统中,同一线程内操作pthread_rwlock时,两种非法解锁场景出现了不同的阻塞表现:
- 场景一:初始化后直接解锁,后续加写锁无限阻塞
#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); // 无限阻塞 }
- 场景二:加锁后多次解锁,后续加写锁不阻塞
#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
相关产品推荐
相关产品推荐

