大佬教程收集整理的这篇文章主要介绍了对fclose进行适当的错误处理是不可能的(根据联机帮助页)?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
通常,使用无缓冲的POSIX功能(打开,关闭,写入等),总有一种方法可以通过重新启动呼叫来从信号中断(EINTR)中恢复;相反,缓冲调用的文档说明在fclose尝试失败后,另一次尝试有未定义的行为…没有关于如何恢复的提示.如果信号中断fclose,我只是“不幸”吗?数据可能会丢失,我无法确定文件描述符是否实际关闭.我知道缓冲区已被释放,但文件描述符呢?
考虑大量使用fd的批量应用程序,如果没有正确释放fd,会遇到问题 – >我认为必须有一个CLEAN解决方案来解决这个问题.
所以我们假设我正在编写一个库并且不允许使用sigaction和SA_RESTART并且发送了大量信号,如果fclose被中断,我该如何恢复?
fclose与EINTR失败后,在循环(而不是fclosE)中调用close是不是一个好主意? fclose的文档根本没有提到文件描述符的状态;虽然UNDEFINED不是很有帮助…如果fd关闭并且我再次打电话给关闭,可能会发生奇怪的难以调试的副作用,所以我宁愿忽略这种情况,因为做了错误的事情……然后,那里没有无限数量的文件描述符可用,资源泄漏是某种错误(至少对我而言).
当然我可以检查fclose的一个具体实现,但我不相信有人设计stdio并且没有考虑这个问题?它只是文档是坏的还是这个函数的设计?
这个角落案件真的让我烦恼:(
事实上,close()也存在问题,而不仅仅是fclose().
POSIX声明close()
返回EINTR,这通常意味着应用程序可能会重试该呼叫.但是Linux中的事情比较复杂.见LWN上的this article和this post.
This blog post和this answer解释了为什么用EINTR重试close()失败并不是一个好主意.所以在Linux中,如果close()因EINTR(或EINPROGRESS)失败,你就无能为力.
另请注意,close()在Linux中是异步的.例如,有时umount可能会在关闭文件系统上的最后一个打开的描述符后立即返回EBUSY,因为它尚未在内核中释放.请参阅此处有趣的讨论:page 1,page 2.
EINTR和fclose()
POSIX指出fclose()
:
我相信这意味着即使close()失败,fclose()也应该释放所有资源并且不会产生泄漏.至少对于glibc和uclibc实现来说这是真的.
可靠的错误处理
>在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()也可能是异步操作.
以上是大佬教程为你收集整理的对fclose进行适当的错误处理是不可能的(根据联机帮助页)?全部内容,希望文章能够帮你解决对fclose进行适当的错误处理是不可能的(根据联机帮助页)?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。