Unix:调用select()时读取文件描述符关闭会发生什么

zer*_*lus 9 c unix

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

R..*_*R.. 4

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

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

当然在多线程程序中,可能最好select根本不使用,而是让多线程中的阻塞IO达到想要的结果,而不需要复杂的加锁逻辑。