c++ - 多线程的 shared_ptr 销毁是否安全?

标签 c++ multithreading shared-ptr

我有两个类似的类:

class Foo {
 public:
  void bar() {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_data.push_back('x');
  }
 private:
  std::string m_data;
  std::mutex m_mutex;
};

class Pool {
 public:
   static std::shared_ptr<Foo> Create(int index) {
     std::lock_guard<std::mutex> lock(m_mutex);
     if (m_pool.size() > 10) {
       m_pool.erase(m_pool.begin());
     }
     std::shared_ptr<Foo>& ptr = m_pool[index];
     if (!ptr) ptr.reset(new Foo);
     return ptr;
   }
 private:
   static std::mutex m_mutex;
   static std::map<int, std::shared_ptr<Foo>> m_pool;
};

和运行这段代码的几个线程:

void parallel_function(int index) {
  // several threads can get the same index
  std::shared_ptr<Foo> foo = Pool::Create(index);
  foo->bar();
}

Cppreference

All member functions (including copy constructor and copy assignment) can be called by multiple threads on different instances of shared_ptr without additional synchronization even if these instances are copies and share ownership of the same object. If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.

两个问题:

  1. 由于 Pool::Create 总是返回 shared_ptr 的拷贝,我假设每个 shared_ptr 的拷贝和销毁是线程安全,如果它发生在 m_pool.erase 中或发生在 parallel_function 的末尾。这是正确的吗?

  2. 我调用了 shared_ptr::operator->,它是一个 const 成员函数,函数 Foo::bar 是线程安全的。这里有数据竞赛吗?

最佳答案

总结一下我的意见。

  1. 是的,这是线程安全的,因为您在不同线程中操作 shared_ptr 的单独拷贝。这是传递 shared_ptr 的拷贝实际上是合理的少数情况之一。
  2. operator-> 是一个 const member .所以基本上你的代码是好的,只要 Foo::bar 是无竞争的(现在显然是这样)。

关于c++ - 多线程的 shared_ptr 销毁是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32750945/

相关文章:

c++ - 我如何判断 OSX 程序是否正在调试器中运行?

c++ - 段错误和运行时错误

python - 从线程迁移到线程

c++ - shared_ptr 的缺点

c++ - VS 代码 "command": "make" differs from command line `make` in terminal window

c++:我如何获得eclipse给我比 "Syntax Error"更多的信息

java - 替代 Thread.suspend() 和 .resume()

windows - 在 Media Foundation 中使用 COINIT_APARTMENTTHREADED 或 COINIT_MULTITHREADED?

c++ - shared_from_this 抛出 bad_weak_ptr 与 boost::asio

c++ - 将 boost::shared_ptr 与重载下标运算符 ([]) 的类一起使用