socket select()如何工作?

时间:2013-02-04 22:12:08

标签: c sockets file-descriptor

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

select(numfds, &read_fds, NULL, NULL, NULL);

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

2 个答案:

答案 0 :(得分:7)

select根据您传入的fd集选择要观看的fds(readfdswritefdsexceptfds)。这些集合通常实现为位向量,因此select将扫描向量以查看选择的fds。作为优化,您传入fds的数量以进行扫描,以便select不必查看最多FD_SETSIZE的所有fds(在编译单元中可能不相同)

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

答案 1 :(得分:6)

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

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