在无限循环中,我正在使用select监听100多个文件描述符。如果fd有一些数据包准备好被读取,我通知分配给该文件描述符的数据包处理器线程,并且我没有为下一轮的该文件描述符设置该位,直到我收到数据处理器线程的通知说它已完成。我想知道如果我不计算最大值,我的代码效率会有多低。我每次清除/设置文件描述符时选择fd。我期待文件描述符几乎是连续的,每个fd的数据到达速率为每秒几千字节。
答案 0 :(得分:4)
您应该使用poll
代替select
。两者都是标准的,但poll
更容易使用,不限制您可以检查的文件描述符的数量(而select
将您限制为编译时常量FD_SETSIZE
) ,效率更高。如果你使用select
,你总是可以传递FD_SETSIZE
作为第一个参数,但这当然会给出最坏的情况,因为内核必须扫描整个fd_set
;传递实际的最大值+ 1允许更短的搜索,但仍然不如传递给poll
的数组有效。
对于它的价值,这些天使用非标准Linux epoll
或任何BSD等价物似乎很时髦。如果你有大量(大约数万个)长寿命(至少几次往返)连接,这些接口可能有一些优点,但是否则性能不会明显更好(并且,在低端,可能更糟糕),这些接口当然是不可移植的,在我看来,比普通的便携式poll
更难正确使用。
答案 1 :(得分:2)
原则上很重要的是给select
一个好的最大fd(但你的过程中只有几百个文件描述符并不重要)。
但是select
正在变得过时(正是由于最大fd,所以内核将采用 O(m)时间,其中<em> m 是最大值。 fd;所以select
如果在一小组文件描述符上使用它可能会很昂贵,这些文件描述符的max m 很大。改为使用poll(2)(当给定一组 n 文件描述符时, O(n)时间,与最大文件描述符 m <无关/ em>的)。
当前的Linux系统和进程可能包含许多数十万个文件描述符。阅读C10K problem。
你可能有一些event loop,例如使用libevent或libev之类的库(可能在内部使用poll
,并且可能使用更多特定于操作系统的内容,例如epoll
等...在方便的界面中抽象它们)