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

问题描述 投票:0回答:2

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

c multithreading pipe posix-select
2个回答
4
投票

您确实应该使用

poll
而不是
select
。两者都是标准的,但
poll
更易于使用,不会限制您可以检查的文件描述符的数量(而
select
限制您使用编译时常量
FD_SETSIZE
),并且效率更高。如果您确实使用
select
,则始终可以将
FD_SETSIZE
作为第一个参数,但这当然会带来最坏情况的性能,因为内核必须扫描整个
fd_set
;传递实际的 max+1 可以缩短搜索时间,但仍然不如传递给
poll
的数组高效。

不管怎样,现在使用非标准 Linux

epoll
或任何 BSD 同等产品似乎很时尚。如果您有大量(数万个)长期(至少几次往返)连接,这些接口可能具有一些优势,但否则性能不会明显更好(并且,在低端,可能更糟),而且这些接口当然是不可移植的,在我看来,比普通的、便携式的
poll
更难正确使用。


2
投票

原则上,为

select
提供一个良好的 max fd 非常重要(但进程中只有几百个文件描述符,这并不重要)。

但是

select
正在变得过时(正是因为最大 fd,因此内核将花费 O(m) 时间,其中 m 是 max.fd;因此,如果在最大
m
很大的一小组文件描述符)。使用 poll(2) 代替(当给定一组 n 文件描述符时,需要 O(n) 时间,与最大文件描述符 m 无关)。 当前的 Linux 系统和进程可能有数十万个文件描述符。了解

C10K 问题

你可能有一些

事件循环

,例如使用像 libeventlibev 这样的库(可能在内部使用 ̀select,并且可能使用更多操作系统特定的东西,比如

poll
等......将它们抽象到一个方便的接口中)
    

© www.soinside.com 2019 - 2024. All rights reserved.