为啥使用 exit() 被认为不好? [复制]

Posted

技术标签:

【中文标题】为啥使用 exit() 被认为不好? [复制]【英文标题】:Why is using exit() considered bad? [duplicate]为什么使用 exit() 被认为不好? [复制] 【发布时间】:2014-08-05 14:45:58 【问题描述】:

我正在阅读this question,有一个答案解释了为什么使用exit() 不好,因为:

您最终会从程序中获得多个退出点 它使代码更加复杂(比如使用 goto) 它无法释放运行时分配的内存

我应该澄清一下我正在使用 Qt,所以代码已经有点“复杂”,因为我正在利用信号和插槽。话虽这么说,对于问题 #1,我看到它与 #2 有关,但我的代码目前试图避免使用 exit(),因为我被告知这会使我的代码看起来一团糟,但避免 exit 已经一团糟。我有不需要返回任何东西的功能,返回东西。例如,当我有用户注册并且他们的用户名已经存在时,而不是在告诉用户注册失败后调用exit()(这是这种情况下所需的行为)我将false返回给一个函数,然后返回@ 987654327@ 到另一个函数,然后将 false 返回到我的主函数,然后检查该函数是否返回 true 或 false,如果返回 false,则返回 0。避免exit() 使代码干净。

对于第三个问题,使用exit(0) 不是告诉操作系统程序已经运行完毕并且操作系统会自行释放内存吗?我运行了一个使用exit(0) 的测试用例,当我按下一个按钮并且该进程从进程列表中删除并且内存被释放时,那为什么还要担心呢?至少在 Windows 上,这似乎是一个彻头彻尾的错误陈述。

【问题讨论】:

操作系统无法清理所有内容。想象一个终止在线连接或将文本刷新到日志文件的析构函数。操作系统对于析构函数中可能发生的事情非常有限。 直接来自对该答案的评论: exit() 不返回。所以不会发生堆栈展开。甚至全局对象也不会被销毁。但是使用 atexit() 注册的函数会被调用。 @Josh 但这似乎不正确,因为我刚刚测试过它并且内存已被清除。 这完全是错误的——几乎每个操作系统都会尽可能地“清理”你的资源——绑定到进程的套接字将被破坏,文件将被关闭等等。但它不能清理你的进程潜在的、无效的数据——如果它在它可以写入你的所有数据之前就结束了……嗯……很明显会发生什么。 是的 - 此后它的定义非常明确,大多数古代人(创建第一个操作系统的人)每天都在创建这样的程序。它被称为“过程编程”。不太可读,有点容易出错,整体丑陋且不可取,但它有效。 【参考方案1】:

只是出于一个简单的原因,在程序中的某处盲目地调用 exit() 被认为是不好的:

它没有正确关闭其他线程(它们只是被终止),它没有正确刷新所有缓冲区(stdio 文件被刷新)并保证永久/共享资源(文件/共享内存/其他方式)的一致和有效状态交流)。

不过,如果您可以保证没有线程正在运行,这可能会干扰(通过持有锁等被杀死),并且所有需要它的缓冲区都将由exit() 刷新,这是实现更快的有效方法关机。

许多现代软件都经过编程以实现更快的关机:

它是容错的,几乎每次都使用例如关闭_Exit()(甚至不调用 atexitat_quick_exit 注册的钩子)是可以的。在大多数情况下,这比有序关闭要快得多(如果可能,应首先销毁 Windows 用户界面资源,因为它们是一个例外)。

进一步阅读:Crash-only software (PDF!)

仅崩溃程序可以安全崩溃并快速恢复。 只有一种方法可以阻止此类软件 - 通过崩溃 它——也是唯一一种方法——通过启动恢复。 仅崩溃系统由仅崩溃组件构建, 以及使用透明的组件级重试 向最终用户隐藏系统内组件崩溃。在 在这篇论文中,我们提倡互联网系统的仅崩溃设计, 表明它可以导致更可靠、可预测的 代码和更快、更有效的恢复。我们提出想法 关于如何构建这种只崩溃的互联网服务,采取 将成功的技术发挥到极致。

【讨论】:

必须明确销毁哪些用户界面资源?进程终止后,Windows 不会回收所有此类对象吗? @Ruslan 是的,Windows 会回收它们。但这比自己明确清理它们要慢(或曾经?)。【参考方案2】:

第 1 项和第 2 项,我不同意。这些更多的是风格和偏好问题。

关于第 3 项,您应该查看文档以了解它实际上会或不会释放或刷新的内容(http://en.cppreference.com/w/cpp/utility/program/exit 和 http://msdn.microsoft.com/en-us/library/6wdz5232.aspx)。例如,MS 文档说“在终止进程之前刷新所有文件缓冲区。”

当你的程序退出时,操作系统会回收内存,但这不是他在说的。他的意思是信号量之类的资源不会被正确或及时地释放。也许这是一个问题,也许不是,这取决于您使用的资源类型。

【讨论】:

以上是关于为啥使用 exit() 被认为不好? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

使用 if(...) 时,为啥这被认为是一种好的编程习惯? [复制]

为啥 Singleton 被认为是反模式? [复制]

为啥 Vector 和 HashTable 被广泛认为应该被弃用? [复制]

为啥 Vector 和 HashTable 被广泛认为应该被弃用? [复制]

为啥从 main() 显式返回 0 被认为是好的做法? [复制]

在 C 中初始化一个 char 指针。为啥被认为是危险的? [复制]