假设我在包含一堆读取文件描述符的FD_SET上调用select()。如果在select()调用期间,其中一个文件描述符关闭会发生什么?假设发生了某种错误,那么我是否有责任从集合中找到并删除已关闭的文件描述符?
答案 0 :(得分:4)
我不相信这是指定的;某些系统可能会立即从select
返回,而其他系统可能会继续阻止。请注意,这种情况发生的唯一方法是在多线程进程中(否则close
不能在select
期间发生;即使它是从信号处理程序发生的,select
也已经被信号打断了)。因此,这种情况可能表明您需要担心更大的问题。如果您正在轮询的其中一个文件描述符可以在select
期间关闭,则更大的问题是可能会在close
之后立即将相同的文件描述符重新分配给新打开的文件(例如,在另一个不相关的线程中打开的文件)。 {1}},然后轮询的线程可能会错误地在“属于”另一个线程的新文件上执行IO。
如果您的数据对象由一组文件描述符组成,这些文件描述符将在多线程程序中使用select
进行轮询,那么您几乎肯定需要使用某种同步原语来控制对该集合的访问,添加或删除文件描述符应该需要一个与select
(或成员上的任何IO)正在进行的可能性相互排斥的锁。
当然在多线程程序中,最好不要使用select
,而是让多个线程中的IO阻塞实现所需的结果,而无需复杂的锁定逻辑。
答案 1 :(得分:1)
select()
系统调用需要三个fd_set
个参数:Send,Receive,Exception。要检查,如果读取文件描述符上发生错误,请将其包含在读取(接收)和错误(exceprion)集中 - 在从select()
返回的异常集中看到它时,会发生异常那个插座,让你有机会找到什么。
通常,具有任何异常的网络套接字将不再适合发送和接收。
答案 2 :(得分:1)
即使您已读取所有已发送的数据,也会将已关闭的套接字视为已准备好读取。 Select将解锁,表示该套接字可用。