当然,函数调用上的while
循环会阻止你的应用程序的范围,但外面的东西仍然必须循环正确吗?它最终会导致一些硬件阻塞事件吗?如何才能将CPU与100%挂钩呢?
答案 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代替轮询有两个主要优点:
sleep
的工作方式也是如此。有一个硬件计时器,该计时器递减计数,然后发送中断。当您执行sleep(1)
时,操作系统会将计时器设置为一秒,然后阻止该过程。当中断进入时,它会解除阻塞进程。
只有一个计时器,但是如果有多个进程正在睡眠,则操作系统会将计时器设置为首先唤醒的计时器,然后在中断进入时,它将取消阻塞第一个进程并为下一个计时器设置计时器一。这种技术称为“计时器队列”。