民意调查和选择之间有什么区别?

时间:2009-06-09 15:58:12

标签: c unix select

我指的是POSIX标准selectpoll系统C API调用。

3 个答案:

答案 0 :(得分:217)

select()调用你创建了三个位掩码来标记你想要读取,写入和错误的套接字和文件描述符,然后操作系统标记哪些实际上有某种活动; poll()让您创建一个描述符ID列表,操作系统使用发生的事件的种类标记每个描述符ID。

select()方法相当笨拙且效率低下。

  1. 流程通常有超过一千个潜在的文件描述符。如果一个长时间运行的进程只打开了一些描述符,但至少有一个描述符已被赋予一个高数字,那么传递给select()的位掩码必须足够大以容纳最高描述符 - 所以整个范围数百个位将被取消,操作系统必须在每次select()调用时循环,才发现它们未被设置。

  2. 一旦select()返回,调用者必须遍历所有三个位掩码以确定发生了什么事件。在很多典型的应用程序中,只有一个或两个文件描述符在任何给定时刻都会获得新的流量,但是所有三个位掩码必须一直读到最后才能发现那些描述符。

  3. 由于操作系统通过重写位掩码向您发出有关活动的信号,因此它们会被破坏,并且不再标记您要侦听的文件描述符列表。您要么必须从保留在内存中的其他列表重建整个位掩码,要么必须在每个memcpy()之后保留每个位掩码的副本以及select()数据块。 1}}来电。

  4. 因此,poll()方法效果更好,因为您可以继续使用相同的数据结构。

    事实上,poll()启发了现代Linux内核中的另一种机制:epoll(),它进一步改进了机制,允许可扩展性又一次飞跃,因为今天的服务器经常需要处理数十个一次成千上万的连接。这是对这项工作的一个很好的介绍:

    http://scotdoyle.com/python-epoll-howto.html

    虽然这个链接有一些很好的图表显示epoll()的好处(你会注意到select()在这一点被认为是如此低效和过时,甚至没有在这些上划线图):

    http://lse.sourceforge.net/epoll/index.html


    更新:这是另一个Stack Overflow问题,其答案提供了有关差异的更多细节:

    Caveats of select/poll vs. epoll reactors in Twisted

答案 1 :(得分:77)

我认为this会回答你的问题:

  

来自Richard Stevens(rstevens@noao.edu):

     

基本区别在于select()的fd_set是一个位掩码和   因此有一些固定的大小。内核是可能的   编译内核时不限制此大小,允许   应用程序将FD_SETSIZE定义为它想要的任何内容(作为注释   在系统标题暗示今天)但它需要更多的工作。 4.4BSD的   内核和Solaris库函数都有此限制。但是我   看到BSD / OS 2.1现在已被编码以避免这个限制,所以就是这样   可行的,只是编程的一个小问题。 :-)有人应该提交一份   Solaris错误报告,看看它是否得到修复。

     

但是,使用poll(),用户必须分配一个pollfd数组   结构,并传递此数组中的条目数,所以有   没有根本限制。正如Casper指出的那样,poll()的系统数量少于   选择,所以后者更便携。还有原创   实现(SVR3)您无法将描述符设置为-1来告诉   内核忽略了pollfd结构中的一个条目   难以从阵列中删除条目; SVR4解决了这个问题。   就个人而言,我总是使用select()而很少使用poll(),因为我移植了我的   代码也适用于BSD环境。有人可以写一个实现   poll()使用select(),对于这些环境,但我从来没有   见过一个。 POSIX正在标准化select()和poll()   1003.1克。

2017年10月更新:

上面提到的电子邮件至少和2001年一样古老;所有现代操作系统(包括BSD)都支持poll()命令(2017)。事实上,有些人认为select() should be deprecated。除了意见之外,poll()周围的可移植性问题不再是现代系统的问题。此外,epoll()已经开发出来(你可以read the man page),并且继续普及。

对于现代开发,您可能不想使用select(),尽管它没有明显的错误。 poll(),它是更现代的进化epoll(),提供与select()相同的功能(和更多),而不受其中的限制。

答案 2 :(得分:1)

它们都是,并且大多相同,但是大小和功能有所不同!

编写迭代器时,每次都需要复制select集!尽管poll解决了此类问题,但代码却很漂亮。另一个不同之处是,poll默认可以处理1024个以上的文件描述符(FD)。 poll可以处理不同的事件以使程序更具可读性,而无需使用很多变量来处理此类工作。由于进行了大量检查,pollselect中的操作是线性且缓慢的。