有没有办法在 libstd++ 中制作原子 shared_ptr ?

use*_*240 2 c++ multithreading gcc atomic c++11

我需要在我的代码中使用原子 shared_ptr - 我有一个单读多写的场景,其中一个小数据结构将被多个线程复制和覆盖。

在看到这个这个(以及我自己的测试)之后,似乎自由原子函数在 GCC 4.9.2 中仍然不起作用。

我试过简单地将 shared_ptr 放在原子中:

#include <atomic>
#include <iostream>
#include <memory>

std::atomic<std::shared_ptr<std::string> > a_var;

void place() {
  std::shared_ptr<std::string> ptr1(new std::string("abc"));
  a_var.store(ptr1);
}

int main(int argc, const char *argv[]) {
  place();
  std::shared_ptr<std::string> ptr2 = a_var.load();
  std::cout<< *ptr2 << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是用g++ --std=c++11 -g <filename> -latomic它编译后会抛出段错误。

似乎正在发生的事情是,在使用复制构造函数创建了store一个 new之后shared_ptr,但它立即被删除,并且在退出placeptr1后被释放,因此*ptr2抛出。

任何想法如何使它工作

Per*_*xty 5

std::atomic<.> 只能与“普通可复制类型”一起使用。

std::shared_ptr<std::string> obviously doesn't satisfy those criteria. Somewhere atomic will be copying the object as a block of memory and violating some invariant of one or more of the classes.

For example we all know that:

std::shared_ptr<std::string> s(new std::string("abc"));
std::shared_ptr<std::string> t;
memcpy(&t,&s,sizeof(std::shared_ptr<std::string>));
Run Code Online (Sandbox Code Playgroud)

Is both compilable and executable to the end of the copy. It's also a guaranteed recipe for disaster.

In your case ptr1 doesn't "know" it's been copied so it deletes the string when it (ptr1) goes out of scope. Then you access the string. Boom. Game Over.

The standard way to achieve what you're doing is to protect the share_ptr with a std::mutex. There is no easy way to provide a lock-free pointer to string. Such an object would usher in a revolution in computing.