我们应该使用poll()还是select()?

时间:2011-12-08 22:09:24

标签: c++ c networking network-programming posix

我完全了解poll()select()之间的主要区别:

  • select()仅支持固定数量的文件描述符
  • 据称,
  • select()支持更多系统
  • poll()允许对事件类型进行稍微细粒度的控制
  • poll()实施可能在某些细节上有所不同

然而,他们都以大致相同的方式完成同样的任务。所以:

我们应该使用poll()还是select()


编辑:我可能会补充一点,我对epoll()不感兴趣,因为可移植性让我感到担忧。此外,libev(ent)也不是一个选项,因为我问这个问题,因为我正在为libev(ent)编写自己的替换库。

6 个答案:

答案 0 :(得分:17)

所有远程现代系统都有poll,它几​​乎在所有方面都是select / pselect的极佳界面:

  • poll允许比select更精细地检测状态。
  • poll对您可以使用的最大文件描述符没有限制(更重要的是,当您未能检查超过FD_SETSIZE限制的文件描述符时,没有严重漏洞。

我可以想到使用poll的唯一缺点是:

  • pselect不同,poll无法原子地取消屏蔽/屏蔽信号,因此您无法使用它来等待包含文件描述符活动和信号的一组事件,除非您求助于自我-pipe trick。
  • poll只有等待超时的毫秒分辨率,而不是微秒(select)或纳秒(pselect)。

当然poll的可移植性不再是考虑因素。任何年龄足够缺少poll的系统都充满了很多漏洞,不应该连接到网络。

总之,除非你有非常特殊的需求(微小的超时间隔,令人讨厌的信号交互,扩展到数百万个持久连接等),我只需使用poll并完成它。正如其他人所提到的,libevent也是一个选项,但它不是干净/安全的代码(它使用select实际上调用危险的UB试图解决select的限制!)和我查找使用libevent的代码通常比直接使用poll的代码复杂得多。

答案 1 :(得分:4)

如果你是为GNU / Linux写作,你应该看一下epoll(7)。

但是对于大多数跨平台支持,您可以考虑使用libevent。 http://libevent.org/

实际上,如果不知道你想要做什么的具体细节,很难推荐单个民意调查/选择实施。

答案 2 :(得分:4)

我实际上会推荐使用boost :: asio,然后你可以尝试两种实现方式并进行测试,看看哪种方式最适合你的设置。

答案 3 :(得分:2)

我会使用libev或libevent。这些库是跨平台的,并且抽象出底层实现的细节(例如poll,select。)

答案 4 :(得分:0)

根据您的具体需求,我建议使用poll::boost::asio。我发现libevent有点麻烦,它有各种各样的东西,它们面向C和/或更高级别的协议处理。

我不推荐select。我已经看到select的实现以奇怪和奇怪的方式无形地失败,因为超出了描述符限制。你能做的最好的事情就是让它以明显的方式失败。也许这对你的申请来说是不太可能的,但我不会机会。

现在poll几乎到处都有select。关于唯一不是Windows的地方。但是,恕我直言,如果您希望跨平台可移植到该平台,最好使用像::boost::asio这样的好包装器,它可以很好地包装最有效的操作系统技术。

答案 5 :(得分:0)

Apple的民意调查()与TTY,IME有关。因此,可移植性是一个问题,因此select()可能是更好的选择。