如何确定文件描述符是否已被关闭?

时间:2011-04-18 17:45:13

标签: c++ c unix system-calls file-descriptor

在投票结束之前,请阅读,我知道有类似的问题(:

这是我的情况 - 我有一个多线程的应用程序。所以,假设我有10个线程。所有这些都从同一个文件描述符中读取(它实际上是一个套接字)。在非常罕见的情况下,当发生严重错误时,套接字应该由其中一个线程shutdown。问题是,这些线程中的任何一个都可以做到这一点。如果套接字关闭失败,则执行_Exit( FAILURE )(我知道,这听起来像是一个糟糕的设计或代码中的问题,但它实际上并非如此,因为这是由非开源的第三个引起的派对lib,有一个bug)。

这就是问题情况 - 所有人都可能同时尝试shutdown套接字。一个关闭它,但其他人无法关闭它(shutdown返回-1,因为套接字已经关闭)并且执行了坏_Exit( FAILURE )并且废弃了所有内容。

显然,我需要额外的检查 - 如果套接字已经关闭(由于某种原因,所有线程都可能因为关闭套接字而失败,然后至少有一个必须执行_Exit,这就是检查返回代码shutdown是不够的)。

好吧,我发现了this问题,看起来这正是我想要做的。 但我知道,任何类型的系统调用都需要时间(当然),并且在确定套接字将被关闭时它依赖于操作系统。

这就是问题 - 如果套接字已经关闭或者由于某些原因无法关闭,我怎么能有所不同? fcntl是否会确保我,如果一个线程已关闭套接字,同时如果其他线程尝试shutdown套接字,它将失败,然后,如果我进行此检查(使用{ {1}}),这对我有用吗?

我还看到了其他答案:“你可以使用fcntlselect”,但它们仍然是系统调用,我不知道它们是否是更好的选择。我也不知道如何使用它们,但我认为这不是什么大问题。

谢谢!


我还可以查看poll设置errno,但“连接”是什么意思? “连接”和“非有效描述符”之间有什么区别

shutdown

另外,令我困扰的是,我试图关闭的FD可能无效,因为我从ENOTCONN The specified socket is not connected. /proc/net/tcp映射,我不知道是否所有文件看起来就像这样,他们看我的操作系统(操作系统肯定是RHEL4或RHEL5,如果这很重要)

卫生署!这太久了,但我无法解释它。

5 个答案:

答案 0 :(得分:4)

我假设你说你的应用程序在关闭套接字后可以合理地继续吗?

似乎更好的方法是让一个中介线程获得来自任何工作线程的套接字关闭请求的通知,通知其他线程套接字现在已经死亡,并负责关闭套接字本身。这消除了对失败原因的担忧,因为它全部在一个线程中处理。

答案 1 :(得分:3)

每当有一个资源被多个线程使用并且可以被其中一个线程释放时,必须使用锁保护所有访问。否则你将有危险的竞争条件。我会在包含文件描述符的int上使用读写锁。任何想要使用fd的线程都应该在它使用它的持续时间内保持读锁定,并且任何想要更改fd变量的线程(例如close并将其替换为-1以防止进一步使用)应该持有写锁。

基本上这与使用动态分配的内存和free相同。

答案 2 :(得分:1)

检查errno是目前最好的选择。从shutdown(2)我可以看到:

  • EBADF s不是有效的描述符
  • ENOTCONN指定的套接字未连接
  • ENOTSOCK s是一个文件,而不是套接字。

我看到它的方式:EBADF表示它已经关闭,ENOCONN表示此描述符后面没有连接(不是三次握手和所有爵士乐)。

找出最佳方法:在致电perror(3)失败后查看shutdown并查看其内容。

干杯

答案 3 :(得分:0)

您是否考虑过用互斥锁保护插座的关闭?通过使用其中一个,您可以确保只有一个线程尝试关闭套接字。在实际关闭套接字之前,您必须进行一些系统调用,即pthread_mutex_init初始化和pthread_mutex_trylock。但是,这些调用应该针对快速返回进行优化。

另一种避免系统调用的方法是自己实现一个互斥锁,这样只有一个线程实际上可以关闭套接字。当然,您必须调整其中一个existing algorithms for mutual exclusion,以便后面的线程不会等待,而只是继续执行。

答案 4 :(得分:0)

正确答案是由R ..处理线程问题。回答“如何找出fd的状态?”问题:fstat()

每POSIX: 对于文件描述符或套接字的任何问题,它将返回-1。 errno将在已关闭的文件描述符或套接字上设置为EBADF。 stat系列调用专门用于测试:文件(stat),链接(lstat)和文件描述符(fstat)。

closeshutdown等其他调用也会在已关闭的fd上返回错误。但是他们的目的是别的,测试连接套接字是一个副作用。

发布,因为提到的其他系统调用不是为了测试文件描述符。我读到的原始问题的一部分。