Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与自身竞争条件_C++_Multithreading_Boost_Race Condition - Fatal编程技术网

C++ 与自身竞争条件

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<

我有一个带有成员函数的类,这些函数需要在执行操作之前在相应的互斥锁上获取boost::unique_锁。 但是,当存在一个现有的boost::unique_lock时调用成员函数时,它会自动死锁

#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
,您必须记住这一点。这有帮助吗?