【问题标题】:When is `std::process::exit` O.K. to use?`std::process::exit` 什么时候可以。使用?
【发布时间】:2017-01-06 19:25:01
【问题描述】:

documentation of std::process::exit 说:

如果需要彻底关闭,建议仅在没有更多析构函数可运行的已知点调用此函数。

也许由于我缺乏系统编程背景,我不知道是否有析构函数在特定点运行以及我是否应该关心。我想到的唯一一件事是等待对文件(或其他内容)的写入操作,在这种情况下,最好将内容保持在干净状态。

还有什么要注意的吗?我怀疑不建议在更大、更复杂的程序中使用,但对于小型工具来说似乎很方便。

【问题讨论】:

标签: rust destructor exit


【解决方案1】:

简答:

  • 几乎在所有情况下都使用panic!()
  • 您几乎可以确保没有任何析构函数可以运行,如果...
    • ...你在main()函数中
    • ...您手动处理堆栈,包括展开(您可能不是...)
  • 有时您可以在退出程序时忽略析构函数,但您需要小心!

稍微长一点的解释

[...] 对于小工具来说似乎很方便。

如果您因为不可恢复的错误而想退出程序,推荐的方法是panic!()。这将展开堆栈(运行所有析构函数)并使用附加信息(包括您可以指定的消息字符串)退出程序。

[...] 如果有析构函数在特定点运行,我是否应该关心。

如果在当前堆栈帧或上面的任何堆栈帧中存在实现Drop 的局部变量,则 个析构函数可以运行。堆栈帧是堆栈内存中的一个区域,它保存函数调用的所有局部变量(松散地说)。函数退出后,所有局部变量都被丢弃,包括调用实现Drop的所有变量的析构函数。

某些析构函数需要运行的概率随着堆栈的深度而增加(“在main() 和当前堆栈帧之间调用了多少函数)。因此,当你不在时,很难对此进行推理main()函数。


类型何时实现Drop?当只是忽略它们是错误的。考虑i32:当我们退出函数时,我们可以......将它留在堆栈内存中,因为它没有任何负面影响(暂时忽略数据安全的特殊情况)。但是,有许多类型确实需要实现Drop。以下是几个类别:

  • 分配堆内存:Box<T>, Vec<T>, HashMap<T>, ...
  • 持有操作系统资源:File, Socket, ...
  • 返回句柄:RefMutexGuard、...
  • ...

不运行这些的析构函数有不同的效果。第一组可能是最无害的:我们会泄漏内存。但是当你退出程序时,操作系统无论如何都会清理所有这些内存。操作系统资源也差不多:文件描述符通常会在程序退出时被操作系统删除。

但运行析构函数还有更多理由。要考虑的重要一点:您通常不知道为什么某些类型实现Drop,但这些类型确实依赖它。当您忽略这一点时,某些不需要的事情可能发生。通常你不会真正注意到,但有时会导致严重的问题。

【讨论】:

  • 一个非常彻底和启发性的答案!当我在解析的文件中发现语法错误时,我一直在不同的地方使用panic!(),但我想避免Thread 'main' panicked... 噪音,只提供有关我发现的问题的信息。如果我的堆栈帧中只有简单的数据类型,如字符串、字符、整数、我只是从中读取的文件、我自己定义的简单枚举和结构,我几乎敢于将清理工作留给操作系统。跨度>
  • @ThomasW 使用Result 将非程序员逻辑错误冒泡回main,然后如果要控制退出代码,请在main 末尾使用std::process::exit到操作系统。使用panic! 处理程序逻辑错误。
  • @ThomasW Shepmaster 说的。我认为你应该阅读the "Error Handling" chapter in the Rust book。另外:String 类型有时感觉“简单”,但它非常复杂(UTF8/Unicode)并且还实现了Drop,因为字符串缓冲区位于堆上。
  • @LukasKalbertodt 我明白关于字符串的意义,但是让操作系统清理它们的内存有什么危险吗?我知道Result 是处理此类错误的最干净的方法。 (除非出现懒惰,因为这种冒泡不会自行发生,需要实施。)
  • @ThomasW 不,操作系统可以毫无问题地清理堆分配的内存。我想提请注意操作系统可能无法处理的析构函数的所有其他原因。关于懒惰:除非已经完成,否则请阅读本章。 Rust 错误处理出奇地优雅,而且通常很简短。 try!() 和其他技巧使这成为可能。
猜你喜欢
  • 2011-02-24
  • 2018-12-12
  • 2012-07-09
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 2011-03-08
相关资源
最近更新 更多