需要在退出前关闭文件描述符吗?

27
当然,在大多数情况下,即使我坚信一个进程应该正确地清理分配的任何资源,我的立即回答也是“是”,但在我的情况下,我有一个长时间运行的系统守护进程,在启动时打开固定数量的文件描述符,并在退出前关闭所有文件描述符。这是一个嵌入式平台,我试图尽可能使代码紧凑,同时不引入任何不良风格。但由于文件描述符无论如何都会在退出之前被关闭,所以这个文件描述符清理代码有什么作用?你总是关闭你的所有文件描述符吗?
5个回答

16

当你使用完文件描述符后关闭它们可以使你的代码更具可复用性和可扩展性。在我看来,这听起来像一个让它们自动关闭的有效理由。


9

是的,关闭文件描述符并释放所有堆内存,即使你知道操作系统会清理它-这样,当你运行valgrind或类似工具时,你不会在结果中得到很多噪音,并且你可以轻松地识别“合法”的fd泄漏。


6

我对于自动清理关闭文件描述符存在的唯一担忧是,如果您关心已写入该文件描述符的任何数据,并且是否可以合理地处理写入失败。

write() 不必阻塞(取决于首次 open() 的方式),并等待数据成功提交,因此在某些情况下,close 可能会失败,因为底层子系统无法提交挂起的写操作,从而导致 close 退出失败并将 errno 设置为 EIO,并且根据您刚刚编写的内容,您可能需要或不需要采取一些纠正措施。

诚然,这是一个特殊情况,您真正关心数据一致性,即 DBMS 类型的应用程序或备份成功/失败的报告。 在许多(大多数?)情况下,实际上并不太重要,您可以放心离开 close() 进行清理/退出处理。


6
在嵌入式平台的美好世界中,很难说会发生什么事情。然而,如果我处于你的情况下,我会手动测试以查看文件ID是否真的被释放。并且,如果空间如此重要,也许你可以在其他地方记录这个事实。

4

man 3 exit:

....
All open stdio(3) streams are flushed and closed.  Files created by tmpfile(3) are removed.

我相信离开主函数会有效地调用exit函数,并返回主函数的返回值。虽然我认为这是不好的编程风格。个人而言,我总是显式地释放/关闭任何已获取的资源。


2
这并没有涉及其他文件描述符,只有标准输入输出和临时文件。 - Ana Betts
@Paul,不错。但是除了流之外,我认为它变得特定于平台。 - Agnel Kurian
10
POSIX规定:调用进程中打开的所有文件描述符、目录流、转换描述符和消息目录描述符都应该在调用exit()、_exit()或_Exit()时被关闭。但这仍然适用于托管实现,不一定适用于嵌入式系统。 - Jonathan Leffler

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