我试图了解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()对请求的(事件)和结果(revents)使用单独的字段,因此您不必担心重新填充被内核覆盖的集合。
...
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个文件描述符被复制并扫描为no 原因,对于每个select()/ poll()调用。如前所述,这个 问题来自于那些select()/ poll()接口的事实 无状态的。
我不明白文件描述符是“复制”和“扫描”的含义。复制在哪里?我不知道“无国籍”是什么意思。谢谢你的澄清。
答案 0 :(得分:4)
“无状态”的意思是“两次通话之间不保留任何内容”。因此,在上述示例中,内核需要重建很多东西。