c++ - Winsock2 select() 函数 : passing {0, 0} 作为超时参数

标签 c++ client-server winsock2

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

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

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

The timeout value {0, 0} indicates select() will return immediately, allowing an application to poll on the select() operation. This should be avoided for performance reasons.

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

最佳答案

I don't really understand, why I should avoid [calling select() with a zero-timeout). If someone could explain, I would appreciate it.

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

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

关于c++ - Winsock2 select() 函数 : passing {0, 0} 作为超时参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45306378/

相关文章:

C++:双向链表删除函数中的段错误

客户端服务器程序和 mode_t

无法弄清楚如何在我的客户端-服务器模型中实现线程

c - 客户端不可预测的异常关闭

c++ - 发送/接收结构而不是 char 数组

c++ - 通过 winsock 发送压缩字符串

c++ - 通过指针或值修改动态二维数组行

c++ - 字符代表前缀 '0x0'的int十六进制数

c++ - c++类之间的交叉转换

vba - 使用 Windows Socket 和 Excel VBA 的轻客户端