c++ 如果在wrlock之前调用unlock,则pthread wrlock方法将阻塞

wwodge7n  于 2023-01-22  发布在  其他
关注(0)|答案(1)|浏览(113)

我正在使用Ubuntu 20.04,遇到了一个奇怪的问题。在我的代码中,如果在初始化pthread_rwlock_t对象之后,在同一线程中,pthread_rwlock_unlock函数在pthread_rwlock_wrlock之前被调用,则执行阻塞。下面是重现该问题的示例代码

#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);  //Blocks indefinitely 
}

但是一旦wrlock被调用,然后unlocked被调用,这种情况就不会发生。

#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);  //Doesn't Block even though unlock is called twice
}
oaxa6hgo

oaxa6hgo1#

pthread_rwlock_init(&rwlock, NULL);

这将初始化一个新的pthread_rwlock_t结构。初始状态是它是未锁定的。它还没有被锁定。

pthread_rwlock_unlock(&rwlock);

这将解锁pthread_rwlock_t结构。但是,正如我们已经确定的那样,它没有被锁定。这是未定义的行为。
但是一旦wrlock被调用,然后unlocked被调用,这种情况就不会发生。
这是不相关的。未定义的行为就是未定义的行为。你对未定义行为的后果没有任何期望。观察到的行为的实际原因,以及为什么它们在大多数相似的情况下不同,是无关紧要的。你可能明天一觉醒来,发现明天两个示例产生同样的结果。这是可能发生的。这就是未定义行为的含义。它是未定义的。你不能抱着它,或期望得到同样的结果每一次。
实际的原因显然与这些锁定原语的内部实现有关。但这仍然是无关的。后天你可能会更新你的内核或C库,未定义行为的实际结果将再次变得不同,因为这个内部逻辑由于某种原因被更新了。你不能依赖它。所以,未定义行为的实际结果没有任何价值或优点。

相关问题