13

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

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

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

4

2 回答 2

9

selectreadfds根据您传入的 fd 集 ( , writefds, )选择要观看的 fd exceptfds。这些集合通常被实现为位向量,因此select将扫描向量以查看选择了哪些 fd。作为一种优化,您传入要扫描的 fd 的数量,这样select就不必查看所有 fd FD_SETSIZE(在编译单元之间甚至可能不一样)。

select是一个相当昂贵的调用,因为每次调用select. 在许多平台上,select它只是在系统调用之上实现poll,它为等待文件描述符提供了更有效的接口。

于 2013-02-04T22:13:32.267 回答
6

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

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

于 2013-02-04T22:17:58.640 回答