C++ 与自身竞争条件
我有一个带有成员函数的类,这些函数需要在执行操作之前在相应的互斥锁上获取boost::unique_锁。 但是,当存在一个现有的boost::unique_lock时调用成员函数时,它会自动死锁C++ 与自身竞争条件,c++,multithreading,boost,race-condition,C++,Multithreading,Boost,Race Condition,我有一个带有成员函数的类,这些函数需要在执行操作之前在相应的互斥锁上获取boost::unique_锁。 但是,当存在一个现有的boost::unique_lock时调用成员函数时,它会自动死锁 #include <iostream> #include "boost/thread.hpp" #include "boost/foreach.hpp" #include <list> class example { private: std::list<
#include <iostream>
#include "boost/thread.hpp"
#include "boost/foreach.hpp"
#include <list>
class example {
private:
std::list< int > int_array;
std::list< int >::iterator array_iterator;
mutable boost::shared_mutex array_mutex;
public:
/*
* Move the iterator forward.
*/
inline example & next( ) {
boost::unique_lock< boost::shared_mutex > lock( array_mutex );
array_iterator++;
if( array_iterator == int_array.end( ) ) {
array_iterator = int_array.begin( );
}
return *this;
}
/*
* Get int_array_mutex.
*/
inline boost::shared_mutex & mutex( ) const {
return array_mutex;
}
/*
* Get int_array.
*/
inline std::list< int > & array() {
return int_array;
}
};
int main() {
example example_instance;
boost::unique_lock< boost::shared_mutex> lock(example_instance.mutex());
//Manipulate int_array...
example_instance.array().push_back(1);
example_instance.array().push_back(2);
example_instance.array().push_back(3);
example_instance.array().push_back(4);
BOOST_FOREACH(int & x, example_instance.array()) {
x++;
}
//Causes deadlock
example_instance.next();
std::cout << "This shall not be emitted." << std::endl;
return 0;
}
#包括
#包括“boost/thread.hpp”
#包括“boost/foreach.hpp”
#包括
课例{
私人:
std::listint\u数组;
std::list::迭代器数组\迭代器;
可变增强::共享互斥数组互斥;
公众:
/*
*向前移动迭代器。
*/
内联示例&next(){
boost::unique_locklock(数组_mutex);
数组_迭代器++;
if(array\u iterator==int\u array.end()){
array_iterator=int_array.begin();
}
归还*这个;
}
/*
*获取int\u数组\u互斥体。
*/
内联boost::shared_mutex&mutex()常量{
返回数组_互斥;
}
/*
*获取int_数组。
*/
内联std::list&数组(){
返回int_数组;
}
};
int main(){
例例(例);;
boost::unique_locklock(example_instance.mutex());
//操纵整数数组。。。
示例_instance.array().向后推_(1);
示例_instance.array().push_back(2);
示例_instance.array()。向后推_(3);
示例_instance.array().push_back(4);
BOOST\u FOREACH(int&x,示例\u instance.array()){
x++;
}
//导致死锁
示例_instance.next();
std::cout我没有使用boost线程,但是如果我正确地读取了代码,您就在主函数中锁定了互斥体,然后调用examlpe\u实例
的next()
方法,该方法还试图获得数组互斥体上的锁…这自然会导致死锁,因为锁似乎不是重入的
为什么要在主功能中获取锁
更新:
不能在同一范围内两次重新获取锁,除非您具有可重入锁(您没有),因此请尝试更改范围:
int main() {
example example_instance;
{// new scope
boost::unique_lock< boost::shared_mutex> lock(example_instance.mutex());
//Manipulate int_array...
example_instance.array().push_back(1);
example_instance.array().push_back(2);
example_instance.array().push_back(3);
example_instance.array().push_back(4);
BOOST_FOREACH(int & x, example_instance.array()) {
x++;
}
}// end scope
// should not cause deadlock now
example_instance.next();
std::cout << "This shall not be emitted." << std::endl;
return 0;
}
intmain(){
例例(例);;
{//新范围
boost::unique_locklock(example_instance.mutex());
//操纵整数数组。。。
示例_instance.array().向后推_(1);
示例_instance.array().push_back(2);
示例_instance.array()。向后推_(3);
示例_instance.array().push_back(4);
BOOST\u FOREACH(int&x,示例\u instance.array()){
x++;
}
}//末端范围
//现在不应该造成僵局
示例_instance.next();
std::cout您需要的是一个更常见的重入互斥体。这将允许您在同一线程内多次锁定同一互斥体,而不会造成死锁。因此,要修复您的示例,只需将共享互斥体的所有实例替换为递归互斥体即可
问题是你现在不能再使用shared\u lock
和upgrade\u unique\u lock
,因为它们都要求你有一个shared\u mutex
。事实证明,根据这些,看起来shared\u mutex
无论如何都是个坏主意。如果你真的需要shared\u mutex
,你就需要shared\u mutex
您必须编写自己的shared\u recursive\u mutex
,因为boost没有提供它。recursive mutex是一种很好的草率编码方法,应该很少使用。OP没有明显的理由想要获得两次锁,而故意这样做通常表明您正在打破锁的基本规则s:尽可能短的保留时间。任何依赖递归锁的设计都应该仔细检查,以确定是否有替代方案,如果没有,则要非常小心地处理,以确保没有缺陷潜入。这就像在类型之间显式转换,一个大的红旗在尖叫“看我!”@Nicholas问题在于,问题没有包含足够的上下文,无法判断他的情况是否真的需要重入互斥。有些情况下,您确实需要重入互斥,但我同意您的看法,这里不太可能是这样。我需要主函数中的锁,以便它可以直接操纵“int_arra”y'。我已经更新了我的示例以反映这一点。@Timesquare:请参阅我的更新。正如我前面所说的:在同一范围内不能锁定两次,除非您有可重入锁(您没有)。因此,当您尝试修改int\u array
,您必须记住这一点。这有帮助吗?