C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了对fclose进行适当的错误处理是不可能的(根据联机帮助页)?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
所以我正在研究fclose manpage,而我的结论是,如果fclose被某些信号中断,根据联机帮助页有没有办法恢复……?我错过了一些观点吗?

通常,使用无缓冲的POSIX功能(打开,关闭,写入等),总有一种方法可以通过重新启动呼叫来从信号中断(EINTR)中恢复;相反,缓冲调用的文档说明在fclose尝试失败后,另一次尝试有未定义的行为…没有关于如何恢复的提示.如果信号中断fclose,我只是“不幸”吗?数据可能会丢失,我无法确定文件描述符是否实际关闭.我知道缓冲区已被释放,但文件描述符呢?
虑大量使用fd的批量应用程序,如果没有正确释放fd,会遇到问题 – >我认为必须有一个CLEAN解决方案来解决这个问题.

所以我们假设我正在编写一个库并且不允许使用sigaction和SA_RESTART并且发送了大量信号,如果fclose被中断,我该如何恢复?
fclose与EINTR失败后,在循环(而不是fclosE)调用close是不是一个好主意? fclose的文档根本没有提到文件描述符的状态;然UNDEFINED不是很有帮助…如果fd关闭并且我再次打电话给关闭,可能会发生奇怪的难以调试的副作用,所以我宁愿忽略这种情况,因为做了错误的事情……然后,那里没有无限数量文件描述符可用,资源泄漏是某种错误(至少对我而言).

当然我可以检查fclose的一个具体实现,但我不相信有人设计stdio并且没有虑这个问题?它只是文档是坏的还是这个函数的设计?

这个角落案件真的让我烦恼:(

解决方法

EINTR和关闭()

事实上,close()也存在问题,而不仅仅是fclose().

POSIX声明close()返回EINTR,这通常意味着应用程序可能会重试该呼叫.但是Linux中的事情比较复杂.见LWN上的this articlethis post.

This blog postthis answer解释了为什么用EINTR重试close()失败并不是一个好主意.所以在Linux中,如果close()因EINTR(或EINPROGRESS)失败,你就无能为力.

另请注意,close()在Linux中是异步的.例如,有时umount可能会在关闭文件系统上的最后一个打开的描述符后立即返回EBUSY,因为它尚未在内核中释放.请参阅此处有趣的讨论:page 1,page 2.

EINTR和fclose()

POSIX指出fclose()

我相信这意味着即使close()失败,fclose()也应该释放所有资源并且不会产生泄漏.至少对于glibcuclibc实现来说这是真的.

可靠的错误处理

>在fclose()之前调用fflush().

由于在调用fflush()或close()时无法确定fclose()是否失败,因此必须在fclose()之前显式调用fflush()以确保成功将用户空间缓冲区发送到内核.
>不要在EINTR之后重试.

如果fclose()使用EINTR失败,则无法重试close(),也无法重试fclose().
>如果需要,请调用fsync().

>如果您关心数据完整性,则应在调用fclose()1之前调用fsync()或fdatasync().
>@R_525_7724@,只需忽略fclose()中的EINTR即可.

笔记

>如果fflush()和fsync()成功并且fclose()因EINTR而失败,则不会丢失任何数据且不会发生泄漏.
>您还应确保在来自另一个线程2的fflush()和fclose()调用之间不使用FILE对象.

[1]参见“Everything You Always Wanted to Know About Fsync()”文章,该文章解释了为什么fsync()也可能是异步操作.

[2]你可以在调用fflush()和fclose()之前调用flockfile().它应该正确使用fclose().

大佬总结

以上是大佬教程为你收集整理的对fclose进行适当的错误处理是不可能的(根据联机帮助页)?全部内容,希望文章能够帮你解决对fclose进行适当的错误处理是不可能的(根据联机帮助页)?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。