为什么阻塞功能不使用100%CPU?

时间:2014-04-16 11:28:22

标签: while-loop message-queue infinite-loop blocking nonblocking

当然,函数调用上的while循环会阻止你的应用程序的范围,但外面的东西仍然必须循环正确吗?它最终会导致一些硬件阻塞事件吗?如何才能将CPU与100%挂钩呢?

1 个答案:

答案 0 :(得分:1)

请记住,操作系统由CPU负责。您的代码只有在操作系统调用它时才能运行。

如果您要求操作系统等待某些东西,则操作系统在该情况发生之前不会调用您的代码

将操作系统调度程序想象成这样的循环:

while(true)
{
    for(Process *p : all_processes)
    {
        RunSomeCodeInProcess(p);
    }
}

这将始终使用100%CPU,即使您的进程未运行。但实际上,循环更像是这样:(仍然简化了)

while(true)
{
    bool all_processes_blocked = false;
    for(Process *p : all_processes)
    {
        if(!IsProcessBlocked(p))
        {
            all_processes_blocked = false;
            RunSomeCodeInProcess(p);
        }
    }
    if (all_processes_blocked)
    {
        StopCPU();
    }
}

操作系统不会打扰正在运行的进程。它将跳过您的进程,仅运行其他进程。如果所有进程被阻止(注意:这是正常的),则操作系统将停止CPU。当CPU停止时,它消耗的功率少得多,产生的热量少,并且不执行指令。这意味着StopCPU将不会返回。

... 直到 CPU从某些硬件设备获得中断,就像鼠标说它已移动一样。然后,CPU将自动再次启动并运行中断处理程序。当中断处理程序返回时,它返回到StopCPU,因此StopCPU返回并且操作系统再次检查未阻塞的进程。硬件中断可能会解除阻止进程之一。例如,如果中断是由于计算机收到了网络数据包,那么现在等待该数据包的进程将被解除阻塞。如果是因为用户按下了键盘上的某个键,那么等待该键的进程将被解除阻止,依此类推。

因此,使用阻塞I / O代替轮询有两个主要优点:

  • 您不会浪费其他进程可以获得的CPU时间。
  • 如果所有进程都被阻止(这是大多数时间 !),CPU可以节省电源和热量。

sleep的工作方式也是如此。有一个硬件计时器,该计时器递减计数,然后发送中断。当您执行sleep(1)时,操作系统会将计时器设置为一秒,然后阻止该过程。当中断进入时,它会解除阻塞进程。

只有一个计时器,但是如果有多个进程正在睡眠,则操作系统会将计时器设置为首先唤醒的计时器,然后在中断进入时,它将取消阻塞第一个进程并为下一个计时器设置计时器一。这种技术称为“计时器队列”。