在select上设置max fd有多重要?

时间:2013-10-03 05:20:47

标签: c multithreading select pipe

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

2 个答案:

答案 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,例如使用libeventlibev之类的库(可能在内部使用poll,并且可能使用更多特定于操作系统的内容,例如epoll等...在方便的界面中抽象它们)