boost :: shared_ptr代码中的多线程错误

时间:2014-01-28 14:23:28

标签: c++ multithreading boost concurrency

我正在使用visual studio,并且我在boost :: shared_ptr代码的以下行继续获得异常:

void release() // nothrow
{
    if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
    {
        dispose();
        weak_release();
    }
}

我认为它是多线程的,因为它发生时非常随机。我很难获得更多细节。

我在几个主题中共享一个unordered_map<std::string, boost::shared_ptr<MyClass>>。我认为错误是由于不同的线程同时访问unordered_map(线程不访问unordered_map的相同元素)。

MyClass包含一个unordered_map和一个集合。线程为这些数据结构添加数字。如果我有:

class MyClass{
public:
    void addToMap(double a, long b);
    void addToSet(double c);
private:
    unordered_map<double, long> a;
    set<double> b;
}
  • 主题1:处理std::unordered_map<std::string, boost::shared_ptr<MyClass> >
  • 的元素1
  • 主题2:处理std::unordered_map<std::string, boost::shared_ptr<MyClass> >
  • 的元素2
  • 主题3:处理std::unordered_map<std::string, boost::shared_ptr<MyClass> >
  • 的元素3
  • 主题4:处理std::unordered_map<std::string, boost::shared_ptr<MyClass> >
  • 的元素4

我的代码中没有任何锁定。有人可以告诉我如何可能解决这个问题(即使这意味着使代码变慢)?我只需要在每个MyClass对象中插入互斥量吗?但是它似乎是导致异常的MyClass对象的boost :: shared_ptr?

我没有通过引用/指针传递任何boost::shared_ptr个对象。

1 个答案:

答案 0 :(得分:2)

operator[]修改容器,因此不能安全地同时访问。您的程序有数据竞争。通常,标准库对象的非const成员函数对于同时访问是不安全的。 C ++11§23.2.2列出了容器的一些特殊例外:

  

1 为避免数据争用(17.6.5.9),实现应将以下函数视为constbeginend,{ {1}},rbeginrendfrontbackdatafindlower_bound,{{1 }},upper_bound和除关联或无序关联容器外,equal_range

     

2 尽管如此(17.6.5.9),当同一序列中不同元素中包含的对象的内容(at除外)同时修改时,需要实现以避免数据争用

因此,对于operator[],多个线程同时调用vector<bool>是不安全的 - 但是它们可以安全地同时访问容器中的不同对象。保护元素的查找就足够了,例如:

unordered_map

或者,如果您只想访问地图中的现有元素 - 而不是添加新的默认构造元素 - 您可以根据上面的标准报价使用operator[]而无需外部同步。