当然,大多数情况下的直接答案是“是”,我坚信一个进程应该正确清理它分配的任何资源,但我的情况是一个长时间运行的系统守护进程,它打开一个固定的启动时文件描述符的数量,并在退出之前将它们全部关闭。
这是一个嵌入式平台,我试图使代码尽可能紧凑,同时不引入任何不好的风格。但是由于文件描述符在退出之前已经关闭,这个文件描述符清理代码有什么用途吗?您是否总是关闭所有文件描述符?
当然,大多数情况下的直接答案是“是”,我坚信一个进程应该正确清理它分配的任何资源,但我的情况是一个长时间运行的系统守护进程,它打开一个固定的启动时文件描述符的数量,并在退出之前将它们全部关闭。
这是一个嵌入式平台,我试图使代码尽可能紧凑,同时不引入任何不好的风格。但是由于文件描述符在退出之前已经关闭,这个文件描述符清理代码有什么用途吗?您是否总是关闭所有文件描述符?
使用完文件描述符后关闭它们会使您的代码更可重用且更易于扩展。在我看来,这听起来像是您有正当理由让它们自动关闭的情况。
是的,关闭你的文件描述符并释放所有堆内存,即使你知道操作系统会清理它——这样,当你运行 valgrind 或一些类似的工具时,你不会在结果中得到很多噪音,并且您可以轻松识别“合法”的 fd 泄漏。
在嵌入式平台的美丽世界里,真的很难说会发生什么。但是,如果我处于您的情况,我只需手动测试以查看文件 ID 是否真的被释放。而且,如果空间如此重要,也许您可以在其他地方记录这一事实。
关于将关闭文件描述符留给自动清理,我会担心的一个问题是,您对写入所述文件描述符的任何数据的关心程度以及您是否可以合理地处理写入失败。
write() 不需要阻塞(取决于它首先是如何打开())并等待数据成功提交,因此在某些情况下关闭可能会失败,因为底层子系统无法提交挂起的写入,因此关闭退出失败并将 errno 设置为 EIO,并且根据您刚刚编写的内容,您可能想要也可能不想采取一些纠正措施。
诚然,这是您真正关心数据一致性的极端情况,即 DBMS 类型的应用程序或报告备份的成功/失败。在许多(大多数?)情况下,这并不重要,您可以不用 close() 来处理清理/退出。
人3退出:
....
All open stdio(3) streams are flushed and closed. Files created by tmpfile(3) are removed.
所以我相信离开 main 有效地调用了带有 main 的返回值的 exit 函数。虽然我认为这是一种糟糕的风格。就个人而言,我总是明确地释放/关闭任何获得的资源。