【问题标题】:std::mutex can't be shared among std::threadstd::mutex 不能在 std::thread 之间共享
【发布时间】:2017-11-15 03:02:05
【问题描述】:

在以下代码中,我认为子线程无法获取 mLooperMutex。但程序输出却相当令人惊讶。看起来std::thread中捕获的mLooperMutex与主线程中的不一样。

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

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

a.out: 主要:等待条件开始
孩子:获取锁开始
孩子:获取锁已完成
孩子:通知一个开始
孩子:通知一个完成
main: 等待条件完成

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

【问题讨论】:

    标签: c++ multithreading c++14


    【解决方案1】:

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

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

    这不适用于.join() 的原因是因为.join() 等待线程完成后才能继续,直到释放锁才能完成线程,而释放锁的looperSet.wait().join() 完成之前不会运行。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 2018-03-21
      • 2013-12-29
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      相关资源
      最近更新 更多