简体   繁体   English

为什么lock_guard可以通过unique_lock获得已经锁定的互斥锁? -还有问题

[英]why lock_guard can get an already locked mutex by unique_lock? - still questions

I am studying this example . 我正在研究这个例子 I have found this question and thought that I will get an answer, but I still have a question. 我已经找到了这个问题,并认为我会得到答案,但是我仍然有一个问题。

I post the the code here for convenience: 为了方便起见,我将代码发布在这里:

std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void worker_thread()
{
    // Wait until main() sends data
    std::cout << "------------------------\n";
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{return ready;});

    // after the wait, we own the lock.
    std::cout << "Worker thread is processing data\n";
    data += " after processing";

    // Send data back to main()
    processed = true;
    std::cout << "Worker thread signals data processing completed\n";

    // Manual unlocking is done before notifying, to avoid waking up
    // the waiting thread only to block again (see notify_one for details)
    lk.unlock();
    cv.notify_one();
}

int main()
{
    std::thread worker(worker_thread);

    data = "Example data";
    // send data to the worker thread
    {
        std::lock_guard<std::mutex> lk(m);
        ready = true;
        std::cout << "main() signals data ready for processing\n";
    }
    cv.notify_one();

    // wait for the worker
    {
        std::unique_lock<std::mutex> lk(m);
        cv.wait(lk, []{return processed;});
    }
    std::cout << "Back in main(), data = " << data << '\n';

    worker.join();

    return 0;
}

Should not the statement std::unique_lock<std::mutex> lk(m); 语句std::unique_lock<std::mutex> lk(m); block the main thread because mutex m is locked by worker_thread ? 阻塞主线程,因为互斥锁mworker_thread锁定了吗? If yes, isn't the statement cv.wait(lk, []{return processed;}); 如果是,则不是语句cv.wait(lk, []{return processed;}); after it unnecessary in this example? 在这个例子中没有必要吗? When main thread can lock the mutex, processed will be already true. 当主线程可以锁定互斥锁时,已processed为true。

The call to wait unlocks the mutex for the duration of the wait. wait的调用会在wait解锁互斥锁。 See http://en.cppreference.com/w/cpp/thread/condition_variable/wait . 请参阅http://en.cppreference.com/w/cpp/thread/condition_variable/wait

EDIT: Which is explicitly stated in the answer to the question you linked to: https://stackoverflow.com/a/32030975/212870 编辑:在您链接到的问题的答案中明确指出: https : //stackoverflow.com/a/32030975/212870

EDIT 2: It is not true that "When main thread can lock the mutex, processed will already be true". 编辑2:并非“当主线程可以锁定互斥锁时,已processed为真”。 The worker thread may not even have started yet, or if it has it may not have seen that ready is set. 工作线程甚至可能尚未启动,或者如果尚未启动,则可能尚未设置ready

Line cv.wait(lk, []{return ready;}); cv.wait(lk, []{return ready;}); does the following if ready is false : 如果readyfalse则执行以下操作:

  1. Unlocks the mutex lk 解锁互斥锁lk

  2. Blocks the thread waiting for notification 阻止线程等待通知

  3. When notification arrives, unblocks the thread and locks the mutex lk 通知到达时,取消阻塞线程并锁定互斥锁lk

So the main thread does not block on std::lock_guard<std::mutex> lk(m); 因此,主线程不会在std::lock_guard<std::mutex> lk(m);上阻塞std::lock_guard<std::mutex> lk(m); as the mutex is unlocked by worker thread. 因为互斥锁是通过工作线程解锁的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM