【问题标题】:object of shared pointer being deleted while instances of shared_ptr are still in scope共享指针的对象被删除,而 shared_ptr 的实例仍在范围内
【发布时间】:2012-02-27 04:03:44
【问题描述】:

我有一个 STL 映射,其中包含指向在多个线程中操作的对象的共享指针。 shared_ptr 拥有的对象正在被删除,而智能指针仍然存在于容器和/或其他函数的范围内。所有 shared_ptr 实例都是按值传递的(因此滥用引用不是问题)。我从这个来源here 得到的印象是,只要存在 shared_ptr 的实例(从现有的 shared_ptr 复制),它拥有的对象就不会被释放。

这基本上是我正在做的事情:

/* Remove Event response in Thread A */
std::map<std::string, std::shared_ptr<object>>::iterator it = objects.find(id);
if(it != objects.end())
{
    std::shared_ptr<object> ob = it->second;
    objects.erase(it);

    //Do cleanup work with ob
}

/* Add Event response in Thread B */
std::map<std::string, std::shared_ptr<object>>::iterator it = objects.find(id);
if(it == objects.end())
{
    std::shared_ptr<object> ob(new object(id));
    objects[id] = ob;

    //Do setup work with ob
}

/* Duty Cycle Event response in Thread C (very frequent) */
//Take snapshot of objects so Remove Event does not invalidate iterators of duty cycle
std::map<std::string, std::shared_ptr<object>> temp_objects = objects; 
for(std::map<std::string, std::shared_ptr<object>>::const_iterator it = temp_objects.begin(); it != temp_objects.end(); ++it)
{
    std::shared_ptr<object> ob = it->second;
    //Access violation can (but doesn't always) occur when dereferencing ob (ob is empty)
}

我做错了什么?我是否滥用了共享指针或对它们的操作方式做出了不正确的假设?

【问题讨论】:

  • 您是否以任何方式同步访问objects
  • 没有。我想,因为我在遍历它们之前制作了objects 的副本,所以这是不必要的。为什么以及如何同步访问会阻止对象被删除?
  • 见尼科尔的回答。 STL 容器不是线程安全的。

标签: c++ boost c++11 shared-ptr


【解决方案1】:

shared_ptr 对象的引用计数是原子的;这是 C++11 所要求的。但是,不需要 std::map 操作 是原子的。他们当然不是。

不保证您可以从一个线程插入并从另一个线程删除,并且仍然保持map 内容的完整性。因此,除非您放入自己的互斥锁或其他一些同步,以防止 map 本身出现竞争条件,否则您的代码将会中断。

这与shared_ptr无关;这只是问题的症状。这是关于包含它们的map

【讨论】:

  • 谢谢尼科尔。这帮助我解决了这个问题。我继续创建this 来解决我的并发问题。
猜你喜欢
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
  • 2021-02-07
相关资源
最近更新 更多