已关闭,此问题为opinion-based。它目前不接受回答。
**想改善这个问题吗?**更新问题,以便editing this post可以用事实和引用来回答。
10天前关闭。
社区在10天前审查了是否重新打开此问题,并将其关闭:
原始关闭原因未解决
Improve this question
如果由于某种原因,我在程序中发现了致命的情况,我想用错误代码退出。有时,致命错误的上下文超出了其他文件描述符的范围。
关闭这些文件描述符是一个好的做法吗?
据我所知,这些文件在进程死亡时会自动关闭。
已关闭,此问题为opinion-based。它目前不接受回答。
**想改善这个问题吗?**更新问题,以便editing this post可以用事实和引用来回答。
10天前关闭。
社区在10天前审查了是否重新打开此问题,并将其关闭:
原始关闭原因未解决
Improve this question
如果由于某种原因,我在程序中发现了致命的情况,我想用错误代码退出。有时,致命错误的上下文超出了其他文件描述符的范围。
关闭这些文件描述符是一个好的做法吗?
据我所知,这些文件在进程死亡时会自动关闭。
7条答案
按热度按时间koaltpgm1#
POSIX编程的经典指南“UNIX环境中的高级编程”指出:
当一个进程终止时,它所有打开的文件都会被内核自动关闭。许多程序利用了这一点,并不显式地关闭打开的文件。
你没有在问题中提到操作系统,但任何操作系统都应该有这样的行为。每当您的程序控制流从
main()
跨越exit()
或return
时,系统负责在流程后进行清理。在操作系统的实现中总是有bug的危险。但是,另一方面,系统必须在进程终止时释放多个打开的文件描述符:可执行文件映像、堆栈、与进程相关的内核对象所占用的内存。您无法从用户空间控制此行为,您只能依赖其按预期工作。那么,为什么程序员不能依赖
fd
s的自动关闭呢?因此,让
fd
s开放的唯一问题可能是编程风格问题。而且,与使用stdio
对象(即围绕系统提供的文件i/o构建的东西),您可能会在valgrinding时收到(有点)令人迷惑的警报。至于泄漏系统资源的危险,应该没有什么可担心的,除非你的操作系统实现真的有bug。bttbmeg02#
文件会自动关闭,但这是一个很好的做法。
参见valgrind关于这个例子
正如您所看到的,它引发了一个内存泄漏
在某些情况下,您可以使用
atexit()
:uqjltbpv3#
据我所知,这些文件在进程死亡时会自动关闭。
别指望那个从概念上讲,当进程死亡时,释放分配的内存、关闭非标准文件描述符等是您的责任。当然,每个正常的操作系统(甚至是Windows)都会在你的过程之后清理干净,但这并不是你所期望的。
xqnpmsa84#
每个正常的操作系统(当然是任何形式的Linux或Windows)都会在程序终止时关闭文件。如果你有一个非常简单的程序,那么你可能不需要在终止时关闭文件。但是,显式关闭文件仍然是一种良好的做法,原因如下:
1.如果你把它留给操作系统,你就无法控制文件的关闭顺序,这可能会导致一致性问题(比如在多文件数据库中)。
1.如果有与关闭文件相关的错误(如I/O错误,空间不足错误等),则无法报告它们。
1.可能存在与需要处理的文件锁定的交互。
1.关闭所有文件的例程可以同时处理程序需要的任何其他清理(例如刷新缓冲区)
gev0vcfq5#
是的。假设你的主程序现在是一个独立程序中的类。你刚刚描述了一个资源泄漏。依赖于全局程序状态,本质上违反了封装。进程的状态-不是你的模块,不是类,不是ADT,不是线程,而是整个进程-处于关闭状态。
u5i3ibmn6#
C保证所有打开的文件将被关闭,如果你的程序正常终止(即。通过
exit
或从main
返回)。但是,如果程序异常终止,例如:它是由操作系统关闭由于使用一个空指针,它是由操作系统来关闭文件。因此,最好确保文件在不再需要时关闭,以防意外终止。另一个原因是资源限制。大多数操作系统对打开的文件数量(以及许多其他内容)都有限制,因此在不再需要这些资源时立即返回这些资源是一个很好的做法。如果每个程序都无限期地打开所有文件,系统可能很快就会出现问题。
piwo6bdm7#
好吧,这段愚蠢的代码可以命名为fd炸弹,因为它在一个新抢占的进程中打开了一个当前目录,并且没有完全退出,所以没有像关闭fd这样的事后资源分配发生:
在WSL 2中测试,使用gcc作为编译器。