c语言 - 使用 select() 时,"set"文件描述符意味着什么?



当使用select((时,我知道过程是:

  1. 在fd_set结构中填充您想知道数据何时进入的文件描述符
  2. 在fd_set结构中填充您想知道何时可以写入的文件描述符
  3. 调用select((并阻止,直到出现问题
  4. select((返回后,对所有文件描述符调用ISSET((,查看它们是否发生了问题,并相应地为它们提供服务
  5. 重复

然而,我不明白的是,文件描述符为"究竟意味着什么;设置";。在本文档中,它表示文件描述符是指定的fd_set的一部分。但是,如果ISSET((检查文件描述符是否发生了什么事情,为什么您要";设置";每个文件描述符在每次迭代开始时,甚至在调用select((之前?他们不应该只是";设置";什么时候发生变化?它们可以是";未设置";在select((返回之前的某个时刻?

读取、写入和异常的选择位是为您希望内核查看的文件句柄设置的。

内核将循环位,直到您在第一个要选择的参数中提供的限制。它会用选择的结果覆盖您发送的位。

select返回它设置的位数,这一点很重要,因为内核不需要检查所有句柄,它可能只在一个句柄之后返回,如果你有很多文件句柄,你应该使用epoll,但无论如何,你可以计算找到的位数,直到它匹配select返回,并避免执行整个位掩码。

(尽管我认为大多数当前的Unixish内核都会扫描所有的位,因为存在一些错误,低编号的文件句柄可能会因为总是报告就绪而使高编号的文件挨饿。(

您可以根据需要设置要发送到select的位掩码。如果希望从套接字读取,请设置其读取位。如果有数据等待写入套接字,请设置写入位。等等

您可能希望始终设置读取位,因为这就是判断套接字已关闭的方法,或者您可以尝试写入已关闭的套接字并获得EPIPE错误。

假设内核将缓冲您对套接字的所有写入,这是一个重大错误,这就是为什么有一个写入位用于select:当有缓冲空间写入更多数据时,它将触发,可能至少有一页4K字节。

最新更新