何时是`std :: process :: exit` O.K.使用?

时间:2016-08-30 13:20:34

标签: rust destructor exit

documentation of std::process::exit说:

  

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

也许是由于我缺乏系统编程背景,我不知道是否有特定点的析构函数,如果我应该关心。我想到的唯一一件事就是对文件(或其他东西)进行写操作,最好将事物保持在干净的状态。

还有其他需要注意的事项吗?我怀疑在较大,更复杂的程序中使用是不可取的,但对于小工具来说似乎很方便。

1 个答案:

答案 0 :(得分:7)

简答:

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

稍微长一点的解释

  

[...]小工具似乎很方便。

如果由于无法恢复的错误而要退出程序,建议的方法是panic!()。这将展开堆栈(运行所有析构函数)并退出程序并附加其他信息(包括您可以指定的消息字符串)。

  

[...]如果有一些析构函数在特定点运行并且我应该关心。

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

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

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

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

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

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