在C语言中,更好的替代exit()和atexit()的方法是什么?

7

我是C编程的新手。我曾经认为使用exit()是最干净的进程终止方式(因为它能够删除临时文件、关闭打开的文件、正常地终止进程...),但当我在终端上尝试man exit命令时(Ubuntu 16.04.5,gcc 5.4.0),我看到了下面这行:

exit()函数使用了一个未受保护的全局变量,所以它不是线程安全的。

之后,我试图研究更好的替换exit()的方法(从一开始改变我的编程行为)。在做这件事的过程中,我遇到了这个问题,在其中提到了exit()的副作用,并建议适当使用atexit()来解决问题(至少部分解决)。

有些情况中,使用abort()优于exit()。除此之外,这个问题表明atexit()也可能有害。

所以我的问题是:

  • 是否有一种通用的、更好的进程终止方式(保证像exit()那样干净,且在任何情况下都不会对系统造成损害)?
  • 如果第一个问题的答案是否定的,那么最佳的进程终止方式是什么(包括它们最有用的情况)?

3
在像Linux、macOS和Windows这样的现代受保护系统中,进程分配的大多数资源不是通过“退出”来释放的,而是由操作系统本身进行释放。而要避免任何资源泄漏的最佳方法仍然是在函数返回之前清理自己创建或分配的任何资源,包括释放、释放或销毁它们。 - Some programmer dude
3
当你开始编写多线程程序时,是考虑 exit() 线程(不)安全的好时机。此外,应对 exit-handler 函数和 atexit() 的价值持怀疑态度。当 exit() 的效果是终止程序时,谁真正关心它是否线程安全呢?仅在特殊情况下 - 可能涉及 atexit() - 才有必要担心它。 - John Bollinger
此外,如果有比 exit() 更好的通用需求,那么这样的功能就已存在。如果 exit() 存在一般性问题,它们将被修复。 - Andrew Henle
1
调用free()函数将虚拟内存返回到即将停止存在的地址空间的堆中是浪费时间的,无论是CPU还是经过的时间。 - user10762593
2个回答

5

如何最佳终止进程?

  1. 如果只有单线程,可以使用exit()来结束进程。
  2. 如果有多个线程,则需要确保除了最后一个线程以外的所有线程都已经结束,然后再安全地调用exit()。这是因为已经满足了第一条。

2
鉴于电源/硬件故障可能随时发生,使用者代码在可靠地终止线程方面的极端困难以及许多非平凡的多线程应用程序中内存池等的混乱性质,更好的方法是设计应用程序和系统,可以在启动时清理临时文件等,而不是试图微观管理关闭。
“在退出之前清理您分配的所有资源”听起来像是课堂或讲座中的好建议,但当面对一打线程、队列和池以及不断变化的动态系统时,它很快就会成为你颈上的一条沉重的铅球链。
如果可以的话,在运行非平凡操作系统下时,让它为您完成清理工作。它比您的用户代码做得更好。

"设计应用程序和系统,可以在启动时清理临时文件等。" 很好的观点!不过,一个良好且干净的关闭也应该是应用程序设计的一部分。如果这不可能,那么就意味着出现了问题。 - alk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接