while循环总是占用CPU的全部用量吗?

gui*_* 桂林 6 c c++ operating-system timer

我需要创建一个服务器端游戏循环,问题是如何限制循环cpu的使用.

根据我的编程经验,繁忙的循环总是占用最大的CPU使用率.但我正在阅读SDL(Simple DirectMedia Layer)的代码,它有一个函数SDL_Delay(UINT32 ms),它有一个while循环,是否需要max cpu使用,如果没有,为什么?

https://github.com/eddieringle/SDL/blob/master/src/timer/unix/SDL_systimer.c#L137-158

do {
    errno = 0;

#if HAVE_NANOSLEEP
    tv.tv_sec = elapsed.tv_sec;
    tv.tv_nsec = elapsed.tv_nsec;
    was_error = nanosleep(&tv, &elapsed);
#else
    /* Calculate the time interval left (in case of interrupt) */
    now = SDL_GetTicks();
    elapsed = (now - then);
    then = now;
    if (elapsed >= ms) {
        break;
    }
    ms -= elapsed;
    tv.tv_sec = ms / 1000;
    tv.tv_usec = (ms % 1000) * 1000;

    was_error = select(0, NULL, NULL, NULL, &tv);
#endif /* HAVE_NANOSLEEP */
} while (was_error && (errno == EINTR));
Run Code Online (Sandbox Code Playgroud)

Gre*_*sev 3

此代码用于select超时。 select通常需要一个文件描述符,并让调用者等待,直到 fd 上发生 IO 事件。它还需要一个超时参数来确定最长等待时间。这里fd为0,所以不会发生任何事件,并且当达到超时时函数总是返回。

select(3)您从 C 库获得的内容是select(2)系统调用的包装器,这意味着调用select(3)最终会让您进入内核。除非发生 IO 事件或达到超时,否则内核不会调度该进程。所以进程在等待时并没有使用CPU。

显然,跳转到内核和进程调度会引入延迟。因此,如果您必须具有非常低的延迟(纳秒),您应该使用忙等待。

  • 如果“select”系统调用收到信号,它会返回 -1 并带有“errno==EINTR”,因此“select”总是在要求的时间休眠是不正确的。 (2认同)