如何知道文件描述符是否被打开?

时间:2014-04-01 23:25:35

标签: c unix

在使用pthread_cancel()的多线程案例中使用open时,我有一些问题。在线程中我需要打开一些文件来阅读。

所以我的第一个问题是,我是否需要将我使用这些打开的文件描述符的字段括在pthread_cleanup_push()pthread_cleanup_pop()中。我认为如果线程被取消,文件仍然打开,那就不太好了。

但是,据我所知,open()函数本身是一个可能的取消点。如果在那里发生取消(或者我在哪里可以得到相关信息,我不知道文件描述符是否被打开?)

最后,是否有一个Unix接口来判断文件描述符是否已打开?

2 个答案:

答案 0 :(得分:2)

  1. 是的,使用pthread_cleanup_push()是一个好主意。

  2. 如果在open()中取消了该线程,则文件描述符将不会打开,因此清理代码只需关闭之前打开的任何内容。

  3. 您可以使用fstat()检查文件描述符是否已打开。或者您可以使用将文件描述符作为参数的其他函数之一,如果描述符未打开,则查找EBADF(错误的文件描述符)。 fstat()的优点是它是一个纯粹的询问函数,而大多数其他人试图改变描述符。 fcntl()也可以进行查询。

答案 1 :(得分:1)

是的,如果某个帖子在保留对打开文件描述符的唯一引用时可以取消,则需要使用pthread_cleanup_push / pop来确保它们已关闭;否则他们会泄漏。

实际上,open函数本身是一个取消点,其他几个资源分配函数(这里是a complete list of cancellation points)也是如此。标准中有一种语言,如果在open发生取消,可以读取要求文件而不是,但我不相信实现已经正确。处理此问题的唯一100%可靠方法是使用pthread_setcancelstate在打开文件(或分配其他资源)时禁用取消,并仅在后续pthread_cleanup_push之后重新启用它。

您可以通过查看no-op fcntl是否因errno设置为EBADF而失败来判断文件描述符是否已打开,但请勿执行此操作。它本质上是完整的 - 在检查和代码控制之间 - 依赖于检查,另一个线程可能会重复使用该文件描述符号,并且您的程序会出现异常,可能是灾难性的(例如,覆盖错误的文件)。