简体   繁体   English

std :: mutex不能在std :: thread之间共享

[英]std::mutex can't be shared among std::thread

In the following codes I suppose mLooperMutex can't be acquired by the children thread. 在以下代码中,我认为子线程无法获取mLooperMutex。 But the program output is quite surprising. 但是节目输出非常令人惊讶。 It looks that mLooperMutex captured in the std::thread is not the same one in main thread. 看起来在std :: thread中捕获的mLooperMutex与主线程中的不同。

But if I changed the detach() call of std::thread to join(), this will lead to a deadlock since the mLooperMutex has been locked by the main thread. 但是如果我将std :: thread的detach()调用更改为join(),这将导致死锁,因为mLooperMutex已被主线程锁定。

Are there anything wrong with this program if I'd like to use the mLooperMutex among different threads? 如果我想在不同的线程中使用mLooperMutex,这个程序有什么问题吗?

a.out: main: wait cond begin a.out:main:等待cond开始
child: acquiring lock begin 孩子:获得锁定开始
child: acquiring lock done 孩子:完成锁定
child: notify one begin 孩子:通知一个人开始
child: notify one done 孩子:通知一个完成
main: wait cond done 主要:等待cond完成

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

using namespace std;

int main()
{
    std::condition_variable looperSet;
    bool child_done = false;
    std::mutex mLooperMutex;

    cout << "main: acquiring lock begin" << endl;
    std::unique_lock<std::mutex> lock(mLooperMutex);
    cout << "main: acquiring lock done" << endl;

    std::thread{[&mutex=mLooperMutex, &looperSet, &child_done] () {
        cout << "child: acquiring lock begin" << endl;
        std::unique_lock<std::mutex> lock(mutex);
        cout << "child: acquiring lock done" << endl;
        child_done = true;
        lock.unlock();

        cout << "child: notify one begin" << endl;
        looperSet.notify_one();
        cout << "child: notify one done" << endl;


    }}.detach();

    cout << "main: wait cond begin" << endl;
    looperSet.wait(lock, [&child_done]{ return child_done; });
    cout << "main: wait cond done" << endl;

    return 0;
}

The reason why the mLooperMutex can be acquired in the child thread is because the lock is released by looperSet.wait : 可以在子线程中获取mLooperMutex的原因是因为looperSet.wait释放了looperSet.wait

// This unlocks "lock", and then locks it again afterwards.
looperSet.wait(lock, [&child_done]{ return child_done; });

The reason why this doesn't work with .join() is because .join() waits for the thread to finish before proceeding, and the thread can't finish until the lock is released, and looperSet.wait() which releases the lock won't run until .join() finishes. 这与.join()不起作用的原因是因为.join()在继续之前等待线程完成,并且线程在释放锁之前无法完成,并且looperSet.wait()释放了在.join()完成之前,lock不会运行。

Creating a thread and then immediately calling .join() is not very useful, you might as well run the code directly rather than using a thread. 创建一个线程然后立即调用.join()并不是很有用,你也可以直接运行代码而不是使用线程。

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

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