在信号处理程序中使用' std::shared_ptr '和' std::weak_ptr '是否安全?
Is it safe to use `std::shared_ptr` and `std::weak_ptr` in a signal handler?
我知道从信号处理程序直接或间接调用malloc
或free
是不安全的。
但是,如果我可以保证至少有一个共享引用将保持活动状态,那么复制构造和销毁其他共享或弱引用是安全的吗?还是我必须自己进行重新计数?
(是的,我知道信号处理程序通常不应该做太多。但是这次我有一个很好的理由。
c++标准对"普通旧函数"的定义如下:
一个POF("普通旧函数")是一个函数,它只使用来自[C/c++]公共子集的特性,它不直接或间接使用任何非POF的函数,除了它可以使用普通的无锁原子操作。
此外:
在c++程序中作为信号处理程序使用的除POF以外的任何函数的行为都是由实现定义的。
显然,c++类对象不是C/c++公共子集的一部分,因此在信号处理程序中使用它们会产生实现定义的行为。
现在,许多实现将允许您有限地使用c++特性。如果你的实现不允许内存分配或异常,那么这就是我们所知道的那些智能指针类型。
则所有weak_ptr
构造函数都显式声明为noexcept
。所以它们不能抛出异常。这也意味着不允许它们分配内存(因为分配内存失败会抛出异常)。是的,如果失败,它们可以分配内存和std::terminate
,但对于实现来说,这样做是非常粗鲁的。
shared_ptr
的copy&move构造函数与noexcept
类似,因此同样适用。对于shared_ptr
的混叠构造函数也是如此。
如果您绝对确定至少有一个shared_ptr
仍然存在,那么明确地声明销毁shared_ptr
没有副作用。这可能包括内存取消分配。
这些都是标准库为您提供的保证。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- 引用 std::shared:ptr 以避免引用计数
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误
- 使用std :: String ptr的错误打印std :: String
- C++中的大小释放:全局运算符delete的正确行为是什么(void*ptr,std::size_t size)
- std::哈希表示无序映射中的唯一 PTR
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- 正确使用std智能指针以确保ptr安全
- 如何创建 std::string 包装器,它将 ptr 保留为 std::string 和 ptr 到创建该包装器实例的
- 为什么 std::string{ "const char ptr" } 有效?
- 为什么 gcc 4.9.0 中没有定义"void operator delete(void* ptr, std::size_t size) noexcept;"?
- 在 std::map 的值中使用非 ptr 是一种很好的做法吗
- 共享 PTR - C++:std::shared_ptr<T> 和 std::shared_ptr<T const> 有什么区别?