简体   繁体   English

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

[英]does while loop always take full CPU usage?

I need create a server side game loop, the problem is how to limit the loop cpu usage. 我需要创建一个服务器端游戏循环,问题是如何限制循环cpu的使用。

In my experience of programming, a busy loop always take maximal CPU usage it could. 根据我的编程经验,繁忙的循环总是占用最大的CPU使用率。 But I am reading the code of SDL(Simple DirectMedia Layer), it has a function SDL_Delay(UINT32 ms) , and it has a while loop, does it take max cpu usage, if not, why? 但我正在阅读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 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));

That loop won't take up all CPU. 该循环不会占用所有CPU。 It utilizes one of two different functions to tell the operating system to pause the thread for a given amount of time and letting another thread utilize the CPU: 它利用两个不同函数中的一个来告诉操作系统暂停线程一段给定的时间并让另一个线程利用CPU:

// First function call - if HAVE_NANOSLEEP is defined.
was_error = nanosleep(&tv, &elapsed);

// Second function call - fallback without nanosleep.
was_error = select(0, NULL, NULL, NULL, &tv);

This code uses select for a timeout. 此代码使用select进行超时。 select usually takes a file descriptor, and makes the caller wait until an IO event occurs on the fd. select通常采用文件描述符,并使调用者等待直到fd上发生IO事件。 It also takes a timeout argument for the maximum time to wait. 它还需要一个超时参数来等待最长时间。 Here the fd is 0, so no events will occur, and the function will always return when the timeout is reached. 这里fd为0,因此不会发生任何事件,并且在达到超时时该函数将始终返回。

The select(3) that you get from the C library is a wrapper around the select(2) system call, which means calling select(3) eventually gets you in the kernel. 你从C库得到的select(3)select(2)系统调用的包装器,这意味着调用select(3)最终会让你进入内核。 The kernel then doesn't schedule the process unless an IO event occurs, or the timeout is reached. 然后,除非发生IO事件或达到超时,否则内核不会调度该进程。 So the process is not using the CPU while waiting. 因此,进程在等待时不使用CPU。

Obviously, the jump into the kernel and process scheduling introduce delays. 显然,跳入内核和进程调度会引入延迟。 So if you must have very low latency (nanoseconds) you should use busy waiting. 因此,如果您必须具有非常低的延迟(纳秒),您应该使用忙等待。

While the thread is blocked in SDL_Delay, it yields the CPU to other tasks. 当线程在SDL_Delay中被阻塞时,它会将CPU产生到其他任务。 If the delay is long enough, the operating system will even put the CPU in an idle or halt mode if there is no other work to do. 如果延迟足够长,操作系统甚至会在没有其他工作要做的情况下将CPU置于空闲或暂停模式。 Note that this won't work well if the delay time isn't at least 20 milliseconds or so. 请注意,如果延迟时间不是至少20毫秒左右,这将无法正常工作。

However, this is usually not the right way to do whatever it is you are trying to do. 但是,这通常不是您正在尝试做的任何事情的正确方法。 What is your outer problem? 你的外在问题是什么? Why doesn't your game loop ever finish doing whatever needs to be done at this time and so then need to wait for something to happen so that it has more work to do? 为什么你的游戏循环在这个时候没有完成任何需要做的事情,所以需要等待一些事情发生,以便它有更多的工作要做? How can it always have an infinite amount of work to do immediately? 如何立即完成无限量的工作?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM