【发布时间】:2016-09-01 03:24:41
【问题描述】:
我试图了解 epoll() 与 select() 和 poll() 有何不同。 select() 和 poll() 非常相似。 select() 允许您监视多个文件描述符,并检查这些文件描述符中的任何一个是否可用于操作(例如读取、写入)而不会阻塞。当超时到期时,select() 返回准备好的文件描述符,程序可以对这些文件描述符执行操作而不会阻塞。
...
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* Don’t rely on the value of tv now! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds) will be true. */
else
printf("No data within five seconds.\n");
...
poll() 更灵活一点,因为它不依赖位图,而是文件描述符数组。此外,由于 poll() 对请求(事件)和结果(事件)使用单独的字段,因此您不必担心重新填充被内核覆盖的集合。
...
struct pollfd fds[2];
fds[0].fd = open("/dev/dev0", ...);
fds[1].fd = open("/dev/dev1", ...);
fds[0].events = POLLOUT | POLLWRBAND;
fds[1].events = POLLOUT | POLLWRBAND;
ret = poll(fds, 2, timeout_msecs);
if (ret > 0) {
for (i=0; i<2; i++) {
if (fds[i].revents & POLLWRBAND) {
...
但是,我读到 poll() 也存在问题,因为 select() 和 poll() 都是无状态的;内核不在内部维护请求的集合。我读到了:
假设有 10,000 个并发连接。通常,只有 其中有一小部分文件描述符,比如 10 个,已准备好 读。其余 9,990 个文件描述符被复制并扫描 原因,对于每个 select()/poll() 调用。如前所述,这 问题来自这样一个事实,即那些 select()/poll() 接口是 无国籍。
我不明白文件描述符是“复制”和“扫描”是什么意思。抄在哪里?而且我不知道“无国籍”是什么意思。感谢您的澄清。
【问题讨论】: