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

Multithreading error within boost::shared_ptr code

本文关键字:多线程 错误 ptr shared boost 代码      更新时间:2023-10-16

我正在使用visual studio,并且在boost的以下行中不断收到异常::shared_ptr code:

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

我认为它是多线程的,因为它发生时是非常随机的。我正在努力了解更多细节。

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

MyClass包含一个无序映射和一个集合。线程为这些数据结构添加数字。所以如果我有:

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对象。

operator[]修改容器,因此并发访问是不安全的。你的程序正在进行数据竞赛。通常,标准库对象的非const成员函数对于同时访问是不安全的。C++11§23.2.2列出了集装箱的一些特殊例外情况:

1为了避免数据争用(17.6.5.9),实现应将以下函数视为constbeginendrbeginrendfrontbackdatafindlower_boundupper_boundequal_rangeat,除在关联或无序关联容器中外,还应考虑operator[]

2尽管有(17.6.5.9),当同时修改同一序列中不同元素(vector<bool>除外)中所包含对象的内容时,需要实现以避免数据竞争。

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

std::unique_lock<std::mutex> lk(some_mutex);
auto& foo = my_map["key"];
lk.unlock();
foo += 42;

或者,如果您只想访问映射中的现有元素,而不想添加新的默认构造的元素,则可以使用find,而不需要按照上面的标准报价进行外部同步。