std::mutex 不能在 std::thread 之间共享
std::mutex can't be shared among std::thread
在下面的代码中,我想mLooperMutex不能被子线程获取。但程序输出相当令人惊讶。看起来在std::thread中捕获的mLooperMutex与主线程中的mLooperMutex不同。
但是如果我将 std::thread 的 detach(( 调用更改为 join((,这将导致死锁,因为 mLooperMutex 已被主线程锁定。
如果我想在不同的线程中使用mLooperMutex,这个程序有什么问题吗?
A.输出: 主:等待电汇开始
子项:获取锁开始
子项:获取锁完成
孩子:通知一个开始
孩子:通知一个完成
主:等待电汇完成
#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()
等待线程完成才能继续,线程在释放锁之前无法完成,而释放锁looperSet.wait()
在.join()
完成之前不会运行。
创建一个线程然后立即调用.join()
不是很有用,你最好直接运行代码而不是使用线程。
相关文章:
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 如何使 std::sort 在 std::swap 和我的命名空间的模板化交换之间没有名称冲突?
- std::is_convertible 和 std::convertible_to 之间的区别(在实践中)?
- std::filesystem 和 std::experimental::filesystem 之间的路径差异
- 在什么条件下使用 std::memcpy 在对象之间复制是安全的?
- std::memmove在同一对象之间是否始终安全
- Cxx.jl 在 Julia Complex 和 std::complex 之间进行转换
- 如何在 std::string 和 Aws::String 之间进行转换?
- std::weak_ptr 和相应的 std::shared_ptr 之间是否存在数据竞争?
- std::fabs(a * b) 和 std::fabs(a) * std::fabs(b) 之间的区别
- 如何在窗口之间移动 std::unique_ptr 而不会冒内存泄漏的风险?
- 简单使用 std::atomic 在两个线程之间共享数据
- "+=" 操作在类型之间不起作用 std::复杂<double>和__complex__双精度
- "std::function<double(double)>"到"double (*)(double)"之间的转换
- malloc 和 calloc 与 std::string 之间的区别
- std::random_device和std::mt19937_64之间有什么区别
- 是std::memcpy在不同的可复制类型之间的未定义行为
- 我收到void main()和使用命名空间std;之间的冲突;?我正在使用代码块
- iostream和命名空间std之间的关系是什么?