有没有办法在 libstdc++ 中创建原子 shared_ptr?

Is there a way of making atomic shared_ptr in libstd++?

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

在看到 this and this(和我自己的测试)后,自由原子函数似乎在 GCC 4.9.2 中仍然不起作用。

我试过简单地将 shared_ptr 放入 atomic:

#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;
}

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

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

关于如何让它发挥作用的任何想法

暂时忘掉 C++11 闪亮的玩具,看看你真正想要实现的目标。

这里要保护的是你的数据结构,而不是引用它的指针。

我假设 "free atomic function" 你的意思是无锁。编译器不允许您随意使用原子是有充分理由的。这是因为在除极少数情况外的所有情况下,这都比使用普通的旧阻塞同步效率低。

C++11 使玩原子变量成为时尚的最新奇想,但尽管这些东西被包裹在一层漂亮的语法糖中,但它非常危险,并且会导致不稳定的 and/or 低效设计除了经验丰富的专家以外的任何人都在使用。

在 C++14 中,您将拥有 atomic_shared_pointer,它需要自定义代码,当然不能仅通过将共享指针包装到原子模板中来使其工作,但无论如何这会也没有解决你的问题。

std::atomic<.> 只能与 'trivially copyable type'.

一起使用

std::shared_ptr<std::string> 显然不满足这些条件。某处 atomic 会将对象复制为内存块并违反 类.

中的一个或多个不变量

比如我们都知道:

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>));

到副本末尾都是可编译和可执行的。这也是灾难的保证。

在您的情况下 ptr1 没有 "know" 它已被复制,因此当它 (ptr1) 超出范围时它会删除该字符串。然后你访问字符串。 繁荣。游戏结束。

实现您正在做的事情的标准方法是用 std::mutex 保护 share_ptr。没有简单的方法来提供指向字符串的无锁指针。这样的对象将引发计算革命。