【问题标题】:Why do destructors run when a panic occurs?为什么发生恐慌时析构函数会运行?
【发布时间】:2018-02-27 11:19:22
【问题描述】:

如果一个 Rust 程序发生恐慌,并且假设没有恐慌捕捉器(有一段时间没有),那么不运行析构函数并让操作系统在进程结束后清理肯定是安全和好的。为什么 Rust 会展开线程?

我能想到的唯一原因是当没有操作系统来回收内存时,但除了那个利基之外,它似乎没有必要。

【问题讨论】:

  • 您可能希望使用析构函数来保存内容,尤其是在出现问题时。
  • 而且对调试很有用。回溯可以帮助您找出问题所在。
  • @lilezek:实际上......你可能不应该依赖析构函数来保存东西。程序可能会中止、崩溃、被操作系统杀死……在任何这些情况下,析构函数都不会运行。在程序终止的上下文中,析构函数只能用于实现“尽力而为”的操作,而不能用于实现“强制”的操作。如果您希望能够从原来的位置恢复,您需要在正常执行期间定期“保存”您的进度(使用原子开关,以防保存期间发生故障......)。
  • @MatthieuM。当我说保存内容时,我的意思是调试信息、TCP 套接字状态……并不是指依赖析构函数将内容保存到磁盘(这甚至可能破坏一些已经存储的数据)。
  • @lilezek:我很高兴我们同意 :) (不幸的是,我接受了“让我们使用析构函数来恢复数据库中的状态”的尝试,并花了几天时间尝试消除损坏)

标签: memory-management rust destructor exception-safety


【解决方案1】:

您的问题有一个错误的前提:它预先假定使用析构函数的唯一原因是清理当前进程的资源。

这确实是最常见的用法,但不是唯一的。

例如,我完全可以想象 TCP 连接的析构函数会尝试发送关闭消息:连接越快关闭,另一端的资源就越快释放。当然,这只是尽力而为(在中止/崩溃的情况下,析构函数永远不会运行),但它仍然是值得的。

【讨论】:

    【解决方案2】:

    如果 Rust 程序出现恐慌 [...],只需让操作系统在进程结束后进行清理。

    线程发生panic时,整个进程不需要退出。在这些情况下,最好运行析构函数。

    在其他情况下,Drop 实现用于执行代码的某些关键部分的“回滚”。

    假设没有恐慌捕捉器(有一段时间没有)

    但是now there are,所以我不清楚你为什么提出这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 2021-09-15
      • 2023-01-26
      • 2018-07-23
      • 2022-06-27
      相关资源
      最近更新 更多