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

Phi*_*lip 15 c c++ networking posix network-programming

我充分意识到之间的主要差异poll()select():

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

但是,它们都以大致相同的方式完成相同的任务.所以:

我们要用poll()还是select()


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

R..*_*R.. 18

所有的远程现代系统中poll,这是一个大大优于接口select/ pselect在几乎所有方面:

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

我能想到的唯一缺点poll是:

  • 不像pselect,poll不能原子地取消屏蔽/屏蔽信号,所以你不能用它来等待包含文件描述符活动和信号的一组事件,除非你求助于自管技巧.
  • poll只有毫秒的等待超时分辨率,而不是微秒(select)或纳秒(pselect).

当然,便携性poll不再是一个考虑因素.任何足够缺乏的系统poll都充满了许多漏洞,它不应该连接到网络.

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

  • 我从来没有在Windows系统上看到过`select`,除非你的意思是在winsock中使用相同名称破坏了不符合要求的功能...... (3认同)
  • 在Windows下,选择(0,NULL,NULL,NULL和&timeout)将立即返回错误代码,而不是在(超时)指定的时间段内休眠.同样在Windows下,异步TCP connect()尝试的失败将仅通过FD_ISSET(sockfd,&exceptionSet)报告,而在我见过的所有其他OS上,它通过FD_ISSET(sockfd,&writeSet)报告.当然可以解决这些差异,但这很烦人:) (2认同)

Pab*_*rin 5

如果您正在为 GNU/Linux 编写代码,则应该查看 epoll(7)。

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

实际上,在不知道您想要做什么的具体情况的情况下,很难推荐单个轮询/选择实现。

  • -1表示推荐`epoll`。它不仅是不可移植的,而且在(非常常见)情况下它的性能要差得多,在这种情况下,您经常在轮询列表中添加和删除文件描述符,因为每个修改操作都需要一个系统调用,并且运行时由系统调用的数量决定。系统调用。除了具有持久连接的大规模服务器(数万或数十万个客户端)之外,“epoll”在任何地方都相当有害。 (2认同)

Nim*_*Nim 5

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