微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用select时,“设置”文件描述符是什么意思?

如何解决使用select时,“设置”文件描述符是什么意思?

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

  1. 使用数据描述符填充您想要知道的fd_set结构,当数据传入时。
  2. 使用何时要写入的文件描述符填充fd_set结构。
  3. 调用select()并阻止,直到发生某些事情为止。
  4. 一旦select()返回,请在所有文件描述符上调用ISSET()以查看它们是否发生了什么,并相应地提供服务。
  5. 重复。

但是,我不明白的是“设置”文件描述符的确切含义。在此documentation中,它表示文件描述符是指定的fd_set的一部分。但是,如果ISSET()检查文件描述符是否发生了什么,为什么还要在每次调用select()之前在每次迭代的开始处“设置”每个文件描述符?难道不是只有当事情发生变化时才被“设定”吗?是否可以在select()返回之前的某个时刻将它们“取消设置”?

解决方法

为要内核查看的文件句柄设置了用于读取,写入和异常的选择位。

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

select返回设置的位数,这很重要,因为不需要内核来检查所有句柄,它可能仅在一个句柄之后返回,并且如果您有很多文件句柄,则应使用epoll ,但是无论如何,您可以计算找到的位数,直到它与选择返回值匹配为止,并避免进行整个位掩码。

(尽管我认为大多数当前的Unixish内核都会扫描所有位,因为存在一些错误,其中低编号的文件句柄可能始终通过报告就绪来使高编号饿死。)

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

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

一个主要的错误是假定内核将缓冲您对套接字的所有写操作,这就是为什么有一个写位供select的原因:它将在有缓冲区空间写入更多数据时触发,至少一页4K字节。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。