我指的是 POSIX 标准选择和轮询系统 C API 调用。
我认为这回答了你的问题:
来自理查德史蒂文斯(rstevens@noao.edu): 基本区别在于 select() 的 fd_set 是一个位掩码,因此具有一些固定大小。当内核被编译时,内核可能不限制这个大小,允许应用程序将 FD_SETSIZE 定义为它想要的任何东西(正如今天系统头文件中的注释所暗示的那样),但这需要更多的工作。4.4BSD 的内核和 Solaris 库函数都有这个限制。但是我看到 BSD/OS 2.1 现在已经被编码以避免这个限制,所以它是可行的,只是编程的小问题。:-) 有人应该就此提交一份 Solaris 错误报告,看看它是否会得到修复。 但是,使用 poll() 时,用户必须分配 pollfd 结构数组,并传递该数组中的条目数,因此没有基本限制。正如 Casper 所指出的,具有 poll() 的系统比 select 少,因此后者更具可移植性。此外,对于原始实现 (SVR3),您无法将描述符设置为 -1 以告诉内核忽略 pollfd 结构中的条目,这使得从数组中删除条目变得困难;SVR4 解决了这个问题。就个人而言,我总是使用 select() 而很少使用 poll(),因为我也将我的代码移植到 BSD 环境中。有人可以为这些环境编写一个使用 select() 的 poll() 实现,但我从未见过。select() 和 poll() 都被 POSIX 1003.1g 标准化。
来自理查德史蒂文斯(rstevens@noao.edu):
基本区别在于 select() 的 fd_set 是一个位掩码,因此具有一些固定大小。当内核被编译时,内核可能不限制这个大小,允许应用程序将 FD_SETSIZE 定义为它想要的任何东西(正如今天系统头文件中的注释所暗示的那样),但这需要更多的工作。4.4BSD 的内核和 Solaris 库函数都有这个限制。但是我看到 BSD/OS 2.1 现在已经被编码以避免这个限制,所以它是可行的,只是编程的小问题。:-) 有人应该就此提交一份 Solaris 错误报告,看看它是否会得到修复。
但是,使用 poll() 时,用户必须分配 pollfd 结构数组,并传递该数组中的条目数,因此没有基本限制。正如 Casper 所指出的,具有 poll() 的系统比 select 少,因此后者更具可移植性。此外,对于原始实现 (SVR3),您无法将描述符设置为 -1 以告诉内核忽略 pollfd 结构中的条目,这使得从数组中删除条目变得困难;SVR4 解决了这个问题。就个人而言,我总是使用 select() 而很少使用 poll(),因为我也将我的代码移植到 BSD 环境中。有人可以为这些环境编写一个使用 select() 的 poll() 实现,但我从未见过。select() 和 poll() 都被 POSIX 1003.1g 标准化。
上面提到的电子邮件至少与 2001 年一样古老;该poll()命令现在(2017 年)在所有现代操作系统(包括 BSD)中都得到支持。事实上,有些人认为select() 应该弃用。除了意见之外,周围poll()的可移植性问题不再是现代系统的问题。此外,epoll()它已经被开发出来(您可以阅读手册页),并且越来越受欢迎。
poll()
select()
epoll()
对于现代开发,您可能不想使用select(),尽管它并没有明显的错误。 poll(),并且它是更现代的进化epoll(),提供相同的功能(以及更多),select()而不受其中的限制。