2012-04-06 111 views
9

假设我在包含一堆读文件描述符的FD_SET上调用select()。如果在select()调用期间发生文件描述符关闭,会发生什么情况?假设发生了某种错误,那么是否有责任从集合中查找并移除关闭的文件描述符?Unix:在调用select()时关闭读文件描述符会发生什么()

+0

请记住,当您在select()调用中时,驻留在fd_set中的filedescriptor的唯一可能方式可以关闭,如果另一个线程关闭()该描述符。 (有一个tcp连接被peer或你本地的tcp/ip栈关闭是另一回事)。 – nos 2012-04-06 16:46:18

+0

另请参阅http://stackoverflow.com/questions/3884110/what-is-select-supposed-to-do-if-you-close-a-monitored-fd – 2012-04-06 18:13:36

回答

4

我不相信这是指定的任何地方;一些系统可能立即从select返回,而其他系统可能会继续阻止。请注意,这种情况发生的唯一方式是在多线程过程中(否则,closeselect期间不会发生;即使它发生自信号处理程序,select也会被信号中断)。因此,这种情况可能表明你有更大的问题需要担心。如果您正在轮询的文件描述符中的一个可以在select期间关闭,则更大的问题是相同的文件描述符可能会被重新分配给紧接在close之后的新打开的文件(例如,在另一个不相关的线程中打开的文件)那么轮询可能会错误地在“属于”另一个线程的新文件上执行IO。

如果你有一个由一组将与select在多线程程序轮询的文件描述符的数据对象,你几乎肯定需要使用某种形式的同步原语来控制访问该组,并加入或删除文件描述符应该需要一个与select(或成员上的任何IO)正在进行的可能性互斥的锁。

当然,在多线程程序中,最好不要使用select,而是让多个线程中的IO阻塞,而不用复杂的锁定逻辑来实现所需的结果。

1

select()系统调用需要三个fd_set参数:发送,接收,异常。要检查,如果读取文件描述符发生错误,请将其包含在读取(接收)和错误(exceprion)集合中 - 在从select()返回的异常集中查看它意味着该套接字发生异常,你有机会找出什么。

一般来说,任何异常的网络套接字将不再适合发送和接收。

+0

实际上'exceptfds'用于紧急数据。 – cnicutar 2012-04-06 16:30:09

+0

http://linux.die.net/man/2/select以及我的经验否则:*“这些[文件描述符]在exceptfds将被监视的例外”* – 2012-04-06 16:34:04

+0

我不喜欢宣传我的答案,但我确实添加了一个链接和一个报价。 – cnicutar 2012-04-06 16:34:48

1

即使您已经读取了所有发送的数据,封闭的套接字始终被视为可以读取。选择将解除阻塞,表明套接字可用。