含义std::互斥锁解锁与锁同步以重新获取

Implications std::mutex unlock synchronizes with lock to reacquiring

本文关键字:新获取 获取 std 解锁 含义 同步      更新时间:2023-10-16

回答完这个问题后,有一件事再次困扰我,让我发疯:

如果一个线程_1当前正在尝试锁定一个互斥锁,而另一个线程_2解锁了这个互斥锁,那么在线程_2再次尝试锁定它之前,是否可以保证线程_1会获得互斥锁。

为了确保当前试图锁定,我假设std::condition_variable::waitstd::mutex::lock具有等效部分,而不仅仅是while(try_lock())

我认为答案是否定的,因为std::mutex实现的调度不同。但我不确定,尽量不做一个名誉妓女,但是,

  1. 这个问题没有当前试图锁定
  2. 这个问题澄清了解锁/锁定部分同步,但没有说明这个一般问题

我只是想确定一下。也许我有点偏执。

演示代码:

#include <thread>
#include <atomic>
#include <mutex>
#include <condition_variable>
#include <cassert>
std::mutex lock; 
std::condition_variable ensure_in_lock;
std::atomic<int> invariant = 1;
void thread_1(){
    while (true){
        std::unique_lock<std::mutex> ul(lock);
        invariant++;
        ensure_in_lock.wait(ul);
        invariant++;
    }
}
void thread_2(){
    while (true){
        lock.lock();
        assert(invariant > 0); //<- This should be, in theory, able to break, shouldn't it?!
        ensure_in_lock.notify_all();
        lock.unlock();
        invariant--;
    }
}
int main(void)
{
    std::thread t1(thread_1);
    /*
    //make sure t1 really had started like with thread_once or pratically with this
    std::this_thread::sleep_for(std::chrono::seconds(1));
    */
    std::thread t2(thread_2);
    while (true);
    return 0;
}

如果一个线程_1当前正试图锁定一个互斥体,而另一个线程_2解锁了该互斥体,那么在线程_2再次尝试锁定互斥体之前,是否可以保证线程_1会获得该互斥体。

不仅没有保证,而且这样的保证将要求实现一个最可怕的实现,最大化上下文切换,而不是最小化它们。如果一个线程可以继续运行,那么您希望让它继续运行并用完它的时间片。您不希望在两个线程之间不断切换,让每个线程的进度都有微小的增量。

锁的好处之一是,它们倾向于取消对争用线程的调度,允许线程运行更长的时间,而不会因争用而导致性能损失。这样的交错要求将否定这种益处。