如网络编程书籍中所述,select()监视一组文件描述符以供阅读。例如,以下是代码的一部分:
select(numfds, &read_fds, NULL, NULL, NULL);
这里numfds
是read_fds + 1中套接字的最大数量。是否意味着,每个“监视”周期select()
都会监视进程的所有文件描述符,从0到numfds?我的意思是,如果我只有两个文件描述符来监视(0和26),是否选择观察从0到26的所有描述符?
答案 0 :(得分:7)
select
根据您传入的fd集选择要观看的fds(readfds
,writefds
,exceptfds
)。这些集合通常实现为位向量,因此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中访问过该代码。