gpt4 book ai didi

c - c 中令人恼火的 select() 行为

转载 作者:太空狗 更新时间:2023-10-29 14:50:14 26 4
gpt4 key购买 nike

while (xxx) {
timeout.tv_sec=TIMEOUT;
timeout.tv_usec=0;
FD_ZERO(&set);
FD_SET(sd,&set);

switch (select(FD_SETSIZE,&set,NULL,NULL,&timeout))
xxxxx
}

工作正常,但是

FD_ZERO(&set); 
FD_SET(sd,&set);

while (xxx) {
timeout.tv_sec=TIMEOUT;
timeout.tv_usec=0;

switch (select(FD_SETSIZE,&set,NULL,NULL,&timeout))
xxxxx
}

没有。它第一次工作,但下一次运行 while 循环时,即使 sd 套接字接收到数据,它也会超时。在我看来,每次都必须清空和填充集是一种资源浪费。

有人能很好地解释为什么会这样,甚至更好的是,也许可以建议如何避免这种情况?

最佳答案

select 修改它的参数。您确实必须每次都重新初始化它。

如果您担心开销,在内核中处理完整 FD_SET 的成本比 FD_ZERO 的成本要高一些。您只想传递最大 fd,而不是 FD_SETSZIZE,以最小化内核处理。在你的例子中:

switch (select((sd + 1),&set,NULL,NULL,&timeout))

对于具有多个 fds 的更复杂的情况,您通常最终会维护一个 max 变量:

FD_SET(sd,&set);
if (sd > max) max = sd;
... repeat many times...

switch (select((max + 1),&set,NULL,NULL,&timeout))


如果你有大量的文件描述符并且担心处理它们的开销,你应该看看 select() 的一些替代方法。你没有提到你正在使用的操作系统,但对于类 Unix 操作系统,有一些:

  • 对于 Linux,epoll()
  • 对于 FreeBSD/NetBSD/OpenBSD/MacOS X,kqueue()
  • 对于 Solaris,/dev/poll

API 各不相同,但它们本质上都是一个有状态的内核接口(interface),用于维护一组事件文件描述。一旦将 fd 添加到集合中,您将收到有关该 fd 的事件通知,而无需不断地再次传递它。

关于c - c 中令人恼火的 select() 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/285790/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com