select系统调用需要 3 个文件描述符集来观察 fds 的可读/可写和文件描述符上的“异常” 。
我的选择手册页没有过多exceptfd
说明描述符集。它是干什么用的; 什么样的异常可以并且会通知文件描述符?
我假设描述符类型可能会有所不同……无论是 TCP 套接字、管道、tty 等)。有没有人有更多关于select
可以报告不同类型描述符的错误的信息?
有时认为需要exceptfds来检测错误,但这是一种误解。错误将在readfds中标记。尽管 POSIX 需要它(甚至调用参数errorfds),但它取决于操作系统是否也在exceptfds中标记错误。确实,只有在您关心异常情况时才需要此参数,但很少需要检测这些情况。
什么是异常情况取决于文件描述符的类型,但到目前为止,最常见的用途是在 TCP 套接字上,它表示可以使用标志读取带外recv()
数据MSG_OOB
。然而,TCP 带外数据有许多怪癖(例如,只有 1 个字节可以突出),因此很少使用。
在最近的 Linux 内核中, exceptfds可用于检测某些 sysfs 属性何时发生变化。可以通过读取 下的相应文件来读取属性的当前值/sys
,并且文件描述符上的 a会在属性更改时select()
标记exceptfds 。但是,这目前仅适用于某些属性和安装更改 ( /proc/mounts
)。
此外,一些设备驱动程序将使用exceptfds标记某些特定于设备的条件。
没错,这取决于您使用文件描述符引用的设备类型。因此,套接字、FIFO、串行端口等是不同的......
查看 read() 的手册页。在底部(至少在 OS X 中)它列出了不同设备可能出现的不同错误。write() 也是如此。
对于套接字、FIFO 和其他 IPC 机制,我会查看 Unix 网络编程,第 1 卷和第 2 卷。IIRC 它描述了针对不同错误条件的预期错误类型。
我曾经用 FIFO 走过这条路。我最终集思广益,讨论了生产者和消费者可以与 FIFO 的每一端交互的所有方式,然后为每种情况编写测试用例。这是发现所有不同错误情况的好方法(尽管很乏味)。我学到了很多东西,最终代码现在可以工作了。