【问题标题】:Better replacement for exit(), atexit() in C更好地替代 C 中的 exit()、atexit()
【发布时间】:2019-03-08 12:35:57
【问题描述】:

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

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

在那之后,我尝试对exit() 的更好替换进行一些研究(从一开始就改变我的编程行为)。这样做时,我遇到了this 问题,其中提到了exit() 的副作用,建议正确使用atexit() 来解决问题(至少部分解决)。

在某些cases 中,使用abort() 优于exit()。最重要的是,this 问题表明atexit() 也可能是有害的。

所以这是我的问题:

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

【问题讨论】:

  • 在 Linux、macOS 和 Windows 等现代受保护系统上,进程分配的大部分资源不是由 exit 释放,而是由操作系统本身释放。避免任何资源泄漏的最好方法仍然是自己清理:您分配或创建的任何资源,在从 main 函数返回之前,您需要解除分配或释放或销毁。
  • 当您开始编写多线程程序时,是开始担心exit() 的线程(非)安全性的好时机。更重要的是,对退出处理函数和atexit() 的价值持怀疑态度。当exit() 的作用是终止程序时,谁真正关心它是否不是线程安全的?只有在特殊情况下——可能涉及atexit()——才有意义。
  • 另外,如果普遍需要比exit() 更好的东西,那么就会存在这样的功能。如果exit() 存在一般性问题,将予以修复。
  • 调用 free() 将虚拟内存返回到将不复存在的地址空间中的堆是浪费时间,包括 CPU 和已用时间。

标签: c linux gcc exit atexit


【解决方案1】:

终止进程的最佳方式是什么

  1. 如果使用单线程,只需使用 exit(),因为您的代码不会使用多线程。
  2. 否则,请确保除了一个线程之外的所有线程都在最后一个线程之前结束,然后由于上述 1. 而安全地调用 exit()

【讨论】:

    【解决方案2】:

    鉴于电源/硬件故障随时可能发生,在许多非平凡的多线程应用程序中,用用户代码可靠地终止线程的极端困难以及内存池使用的混乱本质是不可能的。最好设计可以在启动时清理临时文件等的应用程序和系统,而不是尝试对关机进行微观管理。

    “在你退出之前清理你分配的所有资源”在课堂或讲座中听起来像是个好建议,但当面对不断变化的十几个线程、队列和池时,它很快就会变成一串信天翁。动态系统。

    如果可以的话,如果你在一个非平凡的操作系统下运行,让它完成它的工作并为你清理。它比您的用户代码要好得多。

    【讨论】:

    • 设计可以在启动时清理临时文件等的应用程序和系统”好点!尽管如此,一个漂亮而干净的关机也应该是应用程序设计的一部分。如果这是不可能的,那么某些东西就坏了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    • 2017-02-08
    • 1970-01-01
    • 2021-01-07
    • 2017-11-19
    • 2021-06-30
    • 1970-01-01
    相关资源
    最近更新 更多