我正在使用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;
}
std::unordered_map<std::string, boost::shared_ptr<MyClass> >
std::unordered_map<std::string, boost::shared_ptr<MyClass> >
std::unordered_map<std::string, boost::shared_ptr<MyClass> >
std::unordered_map<std::string, boost::shared_ptr<MyClass> >
我的代码中没有任何锁定。有人可以告诉我如何可能解决这个问题(即使这意味着使代码变慢)?我只需要在每个MyClass对象中插入互斥量吗?但是它似乎是导致异常的MyClass对象的boost :: shared_ptr?
我没有通过引用/指针传递任何boost::shared_ptr
个对象。
答案 0 :(得分:2)
operator[]
修改容器,因此不能安全地同时访问。您的程序有数据竞争。通常,标准库对象的非const
成员函数对于同时访问是不安全的。 C ++11§23.2.2列出了容器的一些特殊例外:
1 为避免数据争用(17.6.5.9),实现应将以下函数视为
const
:begin
,end
,{ {1}},rbegin
,rend
,front
,back
,data
,find
,lower_bound
,{{1 }},upper_bound
和除关联或无序关联容器外,equal_range
。2 尽管如此(17.6.5.9),当同一序列中不同元素中包含的对象的内容(
at
除外)同时修改时,需要实现以避免数据争用
因此,对于operator[]
,多个线程同时调用vector<bool>
是不安全的 - 但是它们可以安全地同时访问容器中的不同对象。保护元素的查找就足够了,例如:
unordered_map
或者,如果您只想访问地图中的现有元素 - 而不是添加新的默认构造元素 - 您可以根据上面的标准报价使用operator[]
而无需外部同步。