c++ - 有没有办法在 libstdc++ 中制作原子 shared_ptr?

标签 c++ multithreading c++11 gcc atomic

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

看到this之后和 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 throw 。

任何让它工作的想法

最佳答案

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

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不“知道”它已被复制,因此当它 ( ptr1 ) 超出范围时它会删除该字符串。然后你访问字符串。 繁荣。游戏结束。

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

关于c++ - 有没有办法在 libstdc++ 中制作原子 shared_ptr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28738004/

相关文章:

c++ - 在嵌套名称说明符中使用枚举(编译器警告)

arrays - Swift 可变数组线程安全

c++ - 为什么 noexcept 在编译时不强制执行?

pointers - C++ 11-一直使用nullptr吗?

c++ - libc++ vs libstdc++ std::is_move_assignable:哪个最正确?

c++ - 生成随机掷骰子并测量结果的频率

c++ - sem_timedwait 与 CLOCK_MONOTONIC_RAW/CLOCK_MONOTONIC

java - 多线程数组比较 - 将事件推送到线程?

java - 如何确保一个线程在另一个线程之后执行?

c++ - 在 Windows 上在 SIZE_T 和 void* 之间转换