初始化原子指针是原子的吗?如果初始化或内存分配引发,会发生什么情况?
Is initializing a atomic pointer atomic? What happens if initialization or memory allocation throws?
如果我一次性声明并定义一个原子指针,就像 -
std::atomic<int*> iptr = new int(1);
std::atomic<T*> iptr = new T();
据我了解,整个操作不是原子的。
new T(( 涉及分配内存,构造 T 对象,然后将其原子分配给 iptr。T 可能是平凡可构造的,在这种情况下,构造 T 不应该抛出,但一些用户定义的 T 可能会抛出。
如果在 T 构造或内存分配之间,其他线程使用 iptr 怎么办?
这个操作真的是原子的吗?使它原子化的一种方法是打破声明和定义,例如
T* temp = new T();
std::atomic<T*> iptr = temp;
有没有其他方法可以在原子上做同样的事情? 我的理解有缺陷吗?
new T()
涉及分配内存,
是的。
构造
T
对象
是的。
然后它将以原子方式分配给 IPTR。
确切地说(几乎,它是此处使用的对象的地址(。它用于在内存分配和构造完成后初始化原子。
T
可能是微不足道的可构造的,在这种情况下,构造T
不应该抛出,但一些用户定义的T
可能会抛出。
如果是这样,则不会达到原子的初始化。如果 c'tor 抛出,new
表达式不会泄漏内存,它会调用正确的去allcoation函数。因此,您的临时表达式和直接使用新表达式具有完全相同的语义。
新的未命名对象的创建不是原子的,但不需要原子的。[如上所述,任何异常只会影响在分配给原子之前创建的临时对象的生存期,并且应该清理得很好。
将该临时指针分配给原子指针是原子指针的。
我最大的担忧是,就目前而言,您的代码无法检测到另一个线程是否完成了分配,因此您必须考虑使用 testandset 或 swap。然后你就会遇到测试/交换失败的麻烦,并且你有一个指向你不再需要的对象的临时指针。
如果您使用局部变量(而不是未命名的临时变量(,则有机会对其进行清理。
如果你对原子和临时使用智能指针,它将自毁。
但是,在许多情况下,除非确实需要临时对象,否则最好不要创建临时对象,但这意味着在整个创建过程中具有互斥锁,但是您可以在输入互斥锁之前进行轻量级检查。这更像是单例静态变量的作用。如果要创建单例,则没有真正的缺点,因为其他线程无论如何都必须等待。
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- 为什么通过指针编译时不能分配 const 初始化
- C++ 手动分配和初始化对象
- 静态分配对象的值初始化
- (为什么)我们可以在初始化中将非静态类成员分配给静态变量吗?
- 分配给已删除/未初始化的对象
- C++初始化列表与分配值
- 动态分配的对象未初始化
- 可视化C++将分配移动到未初始化的对象?
- 如何修复初始化后'stack around variable was corrupted.'变量未更改为分配的值
- 在不放置新运算符的情况下,在预分配的内存上使用虚函数初始化对象 - 这可能吗?如果没有,为什么
- 在 C++ 中初始化后的数组分配
- 将已初始化的基类分配给派生类
- 初始化原子指针是原子的吗?如果初始化或内存分配引发,会发生什么情况?
- 当您通过分配初始化C 对象时会发生什么
- 指向未由对象地址初始化的对象的指针如何将值分配给类的数据成员
- 将空初始化器列表分配给现有向量或地图的效果
- 为什么支撑初始化分配分配填充垃圾变量
- 课堂初始化(分配样式)与构造函数性能
- 如何在构造函数中初始化分配的堆可变量