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