为什么c++并发操作listing_6.1不使用std::recursive_mutex
Why C++ concurrency in action listing_6.1 does not use std::recursive_mutex
我正在阅读《c++ Concurrency In Action》一书,并对清单6.1中使用的互斥锁有一些疑问,代码片段如下:
void pop(T& value)
{
std::lock_guard<std::mutex> lock(m);
if(data.empty()) throw empty_stack();
value=std::move(data.top());
data.pop();
}
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
pop
方法锁定互斥锁,然后调用空互斥锁。但是这个互斥锁不是一个递归互斥锁,代码可以正常工作。所以我怀疑std::mutex
和std::recursive_mutex
到底有什么区别
它正在调用data.empty()
,这似乎是来自数据成员的函数。与您展示的empty
函数不同。
如果是,这将是一个递归调用
bool empty() const
{
std::lock_guard<std::mutex> lock(m);
return data.empty();
}
好吧,recursive_mutex
是为…递归函数!
在某些操作系统中,两次锁定同一个互斥锁可能导致系统错误(在这种情况下,锁可能被完全释放,应用程序可能崩溃,实际上可能发生各种奇怪的和未定义的行为)。
看这个(愚蠢的例子)
void recursivePusher(int x){
if (x>10){
return;
}
std::lock_guard<std::mutex> lock(m);
queue.push(x);
recursivePusher(x+1);
}
这个函数递归地增加x
并将其压入某个共享的queue
。正如我们上面所说的,同一个锁不能被同一个线程锁两次,但是我们确实需要确保共享队列没有被多个线程改变。
一个简单的解决方案是将锁定移到递归函数之外,但是如果我们不能这样做会发生什么?如果被调用的函数是唯一可以锁定共享资源的函数,会发生什么情况?
例如,我的调用函数可能像这样:switch(option){
case case1: recursivly_manipulate_shared_array(); break;
case case2: recursivly_manipulate_shared_queue(); break;
case case3: recursivly_manipulate_shared_map(); break;
}
当然,您不会锁定所有三个(shred_Array、shared_map、shared_queue),因为其中一个会被更改。解决方案是使用std::shared_mutex
:
void recursivePusher(int x){
if (x>10){
return;
}
std::lock_guard<std::recursive_mutex> lock(m);
queue.push(x);
recursivePusher(x+1);
}
如果同一个线程不需要递归地锁定互斥锁,它应该使用常规的std::mutex
,就像你的例子一样。
p。在代码片段中,empty
与T::empty
不同。调用data.empty()
不会递归地调用empty
相关文章:
- 如何在没有死锁和/或争用的情况下正确使用 std::mutex C++?
- std::mutex 如何防止线程修改?
- DRD 报告"conflicting load" std::mutex::lock 上的错误
- std::atomic 和 std::mutex 的相对性能
- 如何解决"'mutex' in namespace 'std' does not name a type"?
- std::lock_guard 怎么可能比 std::mutex::lock() 更快?
- 当"std::lock_guard<std::mutex>"对象没有名称时的不同行为
- std::mutex::lock() 产生奇怪(和不必要的)ASM 代码
- 使用 std::mutex 保护环路
- std::mutex作为一个成员变量对多个线程来说是安全的吗
- std::shared_timed_mutex何时比std::mutex慢,以及何时(不)使用它
- std::mutex 的发布-获取可见性保证是否仅适用于关键部分?
- 死锁使用 std::mutex 来保护多个线程中的 cout
- 返回持有 std::mutex 锁的 RAII 容器类
- 在 C++11 线程中,std::mutex 对内存可见性有什么保证?
- 在任何地方对C++中所有并行线程中的所有锁定和解锁实例使用相同的 std::mutex 和 lock 对象
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- 将 std::atomic<bool> 与 std::mutex 结合使用的正确性
- Inline STD :: MUTEX在标题文件中
- Using std::mutex, std::condition_variable and std::unique_lo