socket select()如何工作?

Tur*_*nov 12 c sockets file-descriptor

如网络编程书籍中所述,select()监视一组文件描述符以供读取.例如,以下是代码的一部分:

select(numfds, &read_fds, NULL, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

numfds是read_fds + 1中套接字的最大数量.是否意味着,每个"监视器"循环都会监视select()进程的所有文件描述符,从0到numfds?我的意思是,如果我只有两个文件描述符来监视(0和26),是否选择观察从0到26的所有描述符?

nne*_*neo 8

select这FDS选择观看基于FD设置你通过在(readfds,writefds,exceptfds).这些集合通常实现为位向量,因此select将扫描向量以查看选择了哪些fds.作为优化,您传入fds的数量以进行扫描,这样select就不必查看所有fds FD_SETSIZE(在编译单元中可能不相同).

select是一个相当昂贵的电话,因为扫描和每次呼叫后重置集的必要性select.在许多平台上,select只是在poll系统调用之上实现,它为等待文件描述符提供了更有效的接口.

  • @TuralGurbanov:是的,它将扫描从"0"到"numfds"的所有内容.如果你想避免这种情况,请使用`poll`(奖励:`poll`不会修改输入数组,所以你不必每次循环都重新添加fds). (3认同)

Jes*_*mos 6

每个监视周期意味着,只要操作系统基本上绕过它,它就可以选择定期检查描述符或通过事件或中断来处理它.当在套接字文件描述符上接收到数据时,描述符文件将填充数据,并通知正在等待它的进程.这并不总是立即发生,因为进程没有立即唤醒它只是简单地放回准备运行队列(因为它被select调用阻止).如果select调用失败(超时中没有收到数据),则计时器将触发并将进程重新置于运行队列中.

FD_SET检查或监控0-26中的fd .这只是为搜索文件描述符设置上限.IIRC这是因为fd_set类型在内部实现为bitset,因为它更容易指定索引,因为这可以节省空间.我之前的陈述可能有误,因为我有一段时间没有访问glibc中的代码.