0

在一个无限循环中,我正在使用 select 监听 100 多个文件描述符。如果 fd 有一些数据包可供读取,我会通知分配给此文件描述符的数据包处理器线程,并且我不会为下一轮设置此文件描述符的位,直到我收到来自数据处理器线程的通知说它已完成. 我想知道如果我不计算最大值,我的代码会有多低效。每次我从集合中清除/设置文件描述符时选择 fd。我期望文件描述符几乎是连续的,每个 fd 的数据到达率是每秒几千字节。

4

2 回答 2

4

你真的应该使用poll而不是select. 两者都是标准的,但poll更易于使用,不会限制您可以检查的文件描述符的数量(而select将您限制为编译时常FD_SETSIZE量),并且更有效。如果你使用select,你总是可以传递FD_SETSIZE第一个参数,但这当然会给出最坏情况下的性能,因为内核必须扫描整个fd_set; 传递实际的 max+1 允许更短的搜索,但仍然不如传递给poll.

epoll就其价值而言,如今使用非标准 Linux或任何等效的 BSD似乎很时尚。如果您有大量(大约数万)长寿命(至少几次往返)连接,这些接口可能具有一些优势,但否则性能不会明显更好(并且,在较低端,可能更糟),这些接口当然是不可移植的,而且在我看来,比普通的、可移植的更难正确使用poll

于 2013-10-03T05:52:35.600 回答
2

原则上,提供一个好的 max fd 是很重要的select(但在您的进程中只有几百个文件描述符并不重要)。

但是select已经过时了(正是因为 max fd,所以内核将花费O(m)时间,其中m是 max.fd;所以如果在 max mselect很大的一小组文件描述符上使用它可能会很昂贵) . 改用poll(2)(当给定一组n文件描述符时,它需要O(n)时间,与最大文件描述符m无关)。

当前的 Linux 系统和进程可能有成千上万的文件描述符。阅读有关C10K 问题的信息。

并且您可能有一些事件循环,例如使用libeventlibev之类的库(可能在poll内部̀,并且可能使用更多操作系统特定的东西,例如epoll等...在一个方便的界面中抽象它们)

于 2013-10-03T05:23:24.800 回答