POSIX怎么读啊
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POSIX怎么读啊相关的知识,希望对你有一定的参考价值。
参考技术A Po-six,组合一下即可。本回答被提问者采纳 参考技术B 这个你可以在百度查下音标,上面会有跟读的,或者用金山词霸也可以查到的如果 posix close call 失败怎么办?
【中文标题】如果 posix close call 失败怎么办?【英文标题】:What to do if a posix close call fails? 【发布时间】:2016-01-11 21:09:43 【问题描述】:在我的系统(Ubuntu Linux,glibc)上,close
调用的手册页指定了它可以返回的几个错误返回值。它还说
不检查 close() 的返回值是一种常见但严重的编程错误。
同时
请注意,返回值应仅用于诊断。特别是 close() 不应该在 EINTR 之后重试,因为这可能会导致来自另一个线程的重用描述符被关闭。
所以我不允许忽略返回值,也不允许重试调用。
鉴于此,我该如何处理close()
调用失败?
如果在我向文件写入内容时发生错误,我可能应该尝试将信息写入其他地方以避免数据丢失。
如果我只是在读取文件,我可以只记录失败并假装什么都没发生过继续程序吗?是否有任何警告、文件描述符泄漏或其他任何问题?
【问题讨论】:
也想过这个。 (unix.stackexchange.com/questions/231677/…) 关闭失败在某些情况下是有意义的(例如,磁盘同步错误),但我认为假设关闭在其他一些情况下不会失败应该是安全的。就像关闭不是指向同一个物理文件的最后一个实例的重复文件描述符的实例或关闭管道一样,因为这些基本上是内核错误,但我希望听到更开明的答案。 FWIW,Raymond Chen 对这种一般情况的看法:blogs.msdn.com/b/oldnewthing/archive/2008/01/07/7011066.aspx 无论你做什么,总是让用户知道。仅仅将它“记录”到一些没有人看过的内部日志文件中是不够的;你会希望用户知道正在发生一些奇怪的事情。对于 GUI 应用程序,我会弹出一个模式对话框。对于命令行应用程序,我会向标准错误打印警告。对于服务,日志文件就足够了。如果在写入文件后发生close()
错误,我会以与在写入文件期间遇到写入错误完全相同的方式中止。
【参考方案1】:
实际上,close
永远不应该在出错时重试,并且在 close
返回后,您传递给 close
的 fd 始终无效(关闭),无论是否发生错误。在某些情况下,错误可能表明数据丢失(某些 NFS 设置)或设备的异常硬件条件(例如,磁带无法倒带),因此您可能需要小心避免数据丢失,但切勿尝试再次关闭 fd。
理论上,POSIX 过去不清楚当close
失败并显示EINTR
时fd 是否保持打开状态,并且系统不同意。由于了解状态很重要(否则您会遇到 fd 泄漏或双重关闭错误,这在多线程程序中非常危险),Austin Group issue #529 的解决方案严格指定了 POSIX 未来版本的行为,EINTR
意味着fd 保持打开状态。这是与别处EINTR
的定义一致的正确行为,但Linux 拒绝接受。 (FWIW 有一个简单的解决方法,可以在 libc 系统调用包装器级别实现;请参阅 glibc PR #14627。)幸运的是,无论如何它在实践中从未出现过。
您可能会发现一些相关的问题:
What are the reasons to check for error on close()? Trying to make close sleep on Linux【讨论】:
所以如果在EINTR
上 fd 保持打开状态,¿尝试再次关闭它是否仍然是错误?在这种情况下我们到底应该怎么做?关闭一个无效的描述符应该返回EINVAL
,所以再试一次不是问题(尽管手册说其他线程在不知情的情况下打开文件描述符,如果其他线程只是打开一个描述符以防你在IO 重定向的中间?---这是一个两阶段的过程)嗯......我们不是试图对机器施加过多的压力吗?
@LuisColorado:根据(修改后的)标准,在EINTR
上,fd 保持打开状态。但是,Linux 不支持这一点,并且 glibc 也无法解决不支持它的问题。请参阅我的答案中的链接。幸运的是,EINTR
在 Linux 上的 close
上不会发生在我所知道的任何真实情况下。
EINTR
可能发生在 NFS 文件系统上的 close(2)
上,网络连接(嗯,在网络 TCP/IP 套接字上内核确实可以工作,但不确定在其他协议上),以及在需要关闭握手的每个设备上(在最后关闭的事情中,取决于从关闭返回的设备驱动程序)并且 linux 不是存在的唯一 POSIX 系统。
@LuisColorado:至少在 Linux 上,release
文件操作不会导致EINTR
(其返回值被忽略),但flush
可以。请参阅我链接的问题。这可能会阻止它在实践中发生,但我可能弄错了。我同意还有其他需要担心的系统。除非您有可用的posix_close
(为 POSIX-future 添加),否则唯一完全安全的做法是在您调用 close
... 时屏蔽所有中断信号... :-(【参考方案2】:
首先:EINTR
的确切含义是:系统调用被中断,如果在close()
调用上发生这种情况,您将无能为力。
除了可能跟踪事实之外,如果 fd 属于文件,则该文件可能已损坏,对于 close()
上的错误您无能为力 - 取决于返回值。 AFAIK 唯一可以重试关闭的情况是 EBUSY
,但我还没有看到。
所以:
不检查close()
的结果可能意味着您错过了文件损坏,尤其是截断。
根据错误,大多数情况下您无能为力 - 失败的 close()
仅表示在您的应用程序范围之外出现了严重错误。
【讨论】:
EINTR
表示系统调用被中断,不会重试,所以根本没有执行。系统没有执行,所以文件描述符没有关闭,必须关闭。系统调用的原子性如何?如果没有执行系统调用并且我们不能再次关闭描述符,那么重复这个过程一堆,每次泄漏一个描述符怎么办?通常,阻塞调用的实现(如 close(),但不适用于普通文件)只是撤消已完成的操作,并为保存的上下文创建一个 longjmp(3)
,只是为了保持原子性。
@LuisColorado 在EINTR
之后重试close()
在Linux 上不是一个好主意。它可能会关闭不同的 fd。
设备驱动程序编写者总是被警告关闭原语,因为它必须独立于硬件条件完成它的工作,返回一个稳定的环境。这意味着设备驱动程序编写者有时必须将资源锁定在内存中,以等待设备响应或将其标记为不可用,直到出现某种情况,但该进程已在一段时间前断开连接。认为设备驱动程序通常不是由编写操作系统的同一个人编写的。我不是专门谈论 linux,而是针对 posix,这意味着很多不同的系统。
那么,close(2)
ing 和 dup(2)
ing 重定向输出在 linux 上也不是一个好主意,因为你可以让其他线程填补这个漏洞。我第一次明白你的信息。原子性确实是一个难题,但不要认为你说的是真话而我不是。此时,没有人编写安全线程来重定向文件描述符,整个系统继续工作而没有痛苦。也许,考虑到close(2)
不是线程安全的并且锁定整个过程的上下文将允许您重试close(2)
调用,直到您安全为止。或泄漏公告。
并且认为如果close(2)
的结果意味着你没有关闭描述符,它不可能移动到别处。你肯定会关闭相同的文件描述符,因为它没有被关闭,它的位置不能被另一个不同的描述符填充(即使在多线程环境中)确实是一个错误是re@987654336 @它没有从第一个检查返回代码,认为它没有关闭并在可能关闭和重新打开的文件描述符上重做系统调用。以上是关于POSIX怎么读啊的主要内容,如果未能解决你的问题,请参考以下文章
使用 R 将日期格式的字符串列表/向量转换为 posix 日期类
ANSIC文件操作和POSIX文件操作对文件的标识分别是啥?