【问题标题】:Winsock2 select() function: passing {0, 0} as timeout parameterWinsock2 select() 函数:传递 {0, 0} 作为超时参数
【发布时间】:2017-07-25 14:32:22
【问题描述】:

我正在使用<winsock2.h> 库创建基于客户端-服务器模型的多人实时游戏。对于通信部分,我决定使用非阻塞套接字,而不是阻塞套接字来消除多线程。 在客户端,我想在一个循环中处理这些任务:

  • 处理用户输入(如有必要)
  • 向/从服务器发送/接收数据(如果可能)
  • 更新游戏数据(以恒定频率)
  • 刷新屏幕(以恒定频率)

我想知道,在循环的第二部分使用超时 {0, 0} 调用 select 是否是一种不好的做法?我找到了this website,上面写着:

超时值 {0, 0} 表示 select() 将立即返回,允许应用程序轮询 select() 操作。 出于性能原因,应避免这种情况。

我真的不明白,为什么我应该避免使用它。如果有人能解释一下,我将不胜感激。

【问题讨论】:

    标签: c++ client-server winsock2


    【解决方案1】:

    我真的不明白,为什么我应该避免[以零超时调用 select())。如果有人 可以解释一下,不胜感激。

    如果您的线程的事件循环从不阻塞任何地方,那么您将以 100% 的 CPU 使用率旋转 CPU。这是低效的,因为您将浪费数万亿个 CPU 周期以最大速度在事件循环中毫无意义地旋转,而实际上并没有做任何工作,因此所有这些 CPU 周期将无法在其他地方使用(例如,其他程序或其他线程)在您自己的程序中)。这也会产生过多的热量并(在笔记本电脑或其他便携式设备上)很快耗尽电池电量。

    更好的方法是计算你需要 select() 何时唤醒(例如,从现在到下一次你需要画一个框架,或者做一些其他的计划任务时还剩下多少时间),然后传入选择的超时参数的时间量。这将导致select() 阻塞(在您指定的时间内),因此允许您的线程在不需要做任何事情的期间休眠。这将在始终使用(至少)一个完整 CPU 内核的程序与仅使用完成其任务实际需要的最少 CPU 时间的程序之间产生差异。

    【讨论】:

      猜你喜欢
      • 2019-02-20
      • 1970-01-01
      • 2021-06-11
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 2020-10-28
      相关资源
      最近更新 更多