c++ - std::mutex 不能在 std::thread 之间共享

标签 c++ multithreading c++14

在下面的代码中,我假设 mLooperMutex 不能被子线程获取。但是程序的输出却相当令人惊讶。看起来 std::thread 中捕获的 mLooperMutex 与主线程中的不同。

但是如果我将 std::thread 的 detach() 调用更改为 join(),这将导致死锁,因为 mLooperMutex 已被主线程锁定。

如果我想在不同线程之间使用mLooperMutex,这个程序有什么问题吗?

a.out: main: wait cond begin
child: acquiring lock begin
child: acquiring lock done
child: notify one begin
child: notify one done
main: wait cond done

#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;
}

最佳答案

之所以能在子线程中获取到mLooperMutex,是因为looperSet.wait释放了锁:

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

这对 .join() 不起作用的原因是因为 .join() 在继续之前等待线程完成,并且线程不能'在锁被释放之前 t 完成,释放锁的 looperSet.wait().join() 完成之前不会运行。

创建一个线程然后立即调用.join()不是很有用,你还不如直接运行代码而不是使用线程。

关于c++ - std::mutex 不能在 std::thread 之间共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47298651/

相关文章:

c++ - 如何在 C++ builder 中渲染 openGL 帧?

python - 为每个操作创建一个线程还是为各种操作创建一些线程?

C++14 逐字提取带引号的字符串,包括引号

c++ - 避免与 1 :N relationship in entity-component-system 相关的缓存未命中

c++ - Object(this) != this 设置的 this 指针

c++ - 在运行时修改功能区控件

c++ - 使用 CUDA-aware MPI 的要求

c++ - std::lock()定义不正确,无法实现还是没用?

c++ - 如何在C++ Windows 7下启动/停止WAV声音

c++ - 使用 clang++ v4 和 gcc 6.3 库的自定义分配器