简体   繁体   English

在信号处理程序中使用`std :: shared_ptr`和`std :: weak_ptr`是否安全?

[英]Is it safe to use `std::shared_ptr` and `std::weak_ptr` in a signal handler?

I know it is not safe for malloc or free to be called, directly or indirectly, from a signal handler. 我知道malloc free ,或者直接或间接地从信号处理程序中free调用。

But, if I can guarantee that at least one shared reference will remain alive, is it then safe to copy-construct and destruct additional shared or weak references, or do I have to roll my own refcounting? 但是,如果我可以保证至少有一个共享引用仍然存在,那么复制构造和销毁其他共享或弱引用是否安全,或者我是否必须自己进行引用计数?

(Yes, I know signal handlers usually shouldn't do much. But I have a good reason this time.) (是的,我知道信号处理人员通常不应该做太多。但这次我有充分的理由。)

The C++ standard defines the concept of a "plain old function" as follows: C ++标准定义了“普通旧函数”的概念,如下所示:

A POF (“plain old function”) is a function that uses only features from [the C/C++] common subset, and that does not directly or indirectly use any function that is not a POF, except that it may use plain lock-free atomic operations. POF(“普通旧函数”)是仅使用来自[C / C ++]公共子集的特征的函数,并且不直接或间接使用任何非POF的函数,除了它可以使用普通锁定 - 免费的原子操作。

Furthermore: 此外:

The behavior of any function other than a POF used as a signal handler in a C++ program is implementation-defined. 除了用作C ++程序中的信号处理程序的POF之外的任何函数的行为都是实现定义的。

Obviously, C++ class objects are not part of the C/C++ common subset, and therefore using them in a signal handler yields implementation-defined behavior. 显然,C ++类对象不是C / C ++公共子集的一部分,因此在信号处理程序中使用它们会产生实现定义的行为。

Now, many implementations will allow you limited usage of C++ features. 现在,许多实现将允许您限制使用C ++功能。 If your implementation doesn't permit memory allocations or exceptions, then here's what we know about those smart pointer types. 如果您的实现不允许内存分配或异常,那么这就是我们对这些智能指针类型的了解。

Then all weak_ptr constructors are explicitly declared noexcept . 然后,所有weak_ptr构造函数都显式声明为noexcept So they can't throw exceptions. 所以他们不能抛出异常。 This also means that they're not allowed to allocate memory (since failing to allocate memory would throw an exception). 这也意味着它们不被允许分配内存(因为无法分配内存会引发异常)。 Yes, they could allocate memory and std::terminate if it fails, but that would be exceedingly rude for an implementation to do. 是的,如果失败,他们可以分配内存和std::terminate ,但这对于实现来说是非常粗鲁的。

The copy&move constructors of shared_ptr similarly is noexcept , so the same applies. shared_ptr复制和移动构造函数同样是noexcept ,因此同样适用。 This is also true for the aliasing constructor for shared_ptr . 对于shared_ptr的别名构造函数也是如此。

If you are absolutely certain that at least one shared_ptr will still exist, then destroying a shared_ptr is explicitly stated to not have side effects. 如果您完全确定至少有一个shared_ptr仍然存在,则明确声明销毁shared_ptr没有副作用。 Which probably includes memory de-allocations. 其中可能包括内存取消分配。

Those are the guarantees that the standard library gives you. 这些是标准库为您提供的保证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM