我正在使用 <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/