9

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

4

3 回答 3

4

我不相信这是在任何地方指定的;一些系统可能会立即返回,select而其他系统可能会继续阻塞。请注意,这可能发生的唯一方法是在多线程进程中(否则,在close期间不会发生select;即使它发生在信号处理程序中,select也会被信号中断)。因此,出现这种情况可能表明您有更大的问题需要担心。如果您正在轮询的文件描述符之一可以在 期间关闭select,更大的问题是相同的文件描述符可能会在close然后可能会错误地对“属于”不同线程的新文件执行 IO。

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

当然在多线程程序中,最好不要使用select,而是让多线程中的阻塞 IO 达到预期的效果,而不需要复杂的锁定逻辑。

于 2012-04-06T16:27:42.103 回答
1

系统select()调用需要三个fd_set参数:Send、Receive、Exception。要检查,如果读取文件描述符上发生错误,请将其包含在读取(接收)和错误(异常)集中 - 在返回时的异常集中看到它select()意味着,该套接字上发生了异常,给你有机会发现什么。

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

于 2012-04-06T16:24:27.173 回答
1

即使您已经读取了所有发送的数据,关闭的套接字也始终被视为已准备好读取。Select 将解除阻塞,表示该套接字可用。

于 2012-04-06T16:26:02.007 回答