【问题标题】:pthread wrlock method blocks if unlock is called before wrlock如果在 wrlock 之前调用 unlock,则 pthread wrlock 方法会阻塞
【发布时间】:2023-01-18 20:16:42
【问题描述】:

我正在使用 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
}

【问题讨论】:

  • 不知道发生了什么。但我有一个问题,你为什么要使用 pthreads?和 std::thread(或 std::async)和内置的读/写锁。 std::shared_lock, std::unique_lock + std::mutex,.使用这些原语的优势:标准 C++ 和 unique_lock/shared_lock 是 RAII 对象,因此当它们超出范围时总是解锁(异常安全)。

标签: c++ pthreads


【解决方案1】:
pthread_rwlock_init(&rwlock, NULL);

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

pthread_rwlock_unlock(&rwlock);

这将解锁 pthread_rwlock_t 结构。然而,正如我们已经确定的那样,它没有被锁定。这是未定义的行为。

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

这无关紧要。未定义的行为是未定义的行为。您对未定义行为的后果没有任何期望。观察到的行为的实际原因,以及它们在大多数相似情况下的不同之处,并不重要。您明天醒来可能会发现明天两个实例都会产生相同的结果。那有可能发生。这就是未定义行为的含义。它是未定义的。你不能用双臂拥抱它,也不能期望每次都得到相同的结果。

实际原因显然与这些锁定原语的内部实现有关。但这仍然无关紧要。后天你可能更新你的内核或C库,未定义行为的实际结果又会变得不一样,因为这个内部逻辑因为某种原因被更新了。你不能依赖它。因此,未定义行为的实际结果没有任何价值或优点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多