Question

Sure, the while loop over the function call blocks inside your app's scope, but something outside still has to be looping right? Does it finally lead up to some hardware blocking event? How else can the CPU not be pegged at 100%?

Was it helpful?

Solution

Remember that the operating system is in charge of the CPU. Your code only gets to run when the operating system calls it.

If you ask the operating system to wait for something, the operating system won't call your code until that thing happens.

Imagine the operating system scheduler as a loop like this:

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

This would always use 100% CPU, even if your process wasn't running. But actually, the loop is more like this: (still simplified)

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();
    }
}

The OS will not bother running processes that are blocked. It will skip over your process and only run other processes. If all processes are blocked (note: this is normal) then the OS will stop the CPU. When the CPU is stopped, it uses way less power, creates way less heat, and it doesn't execute instructions. That means StopCPU won't return.

... until the CPU gets an interrupt from some hardware device, like a mouse saying it got moved. Then the CPU automatically starts up again and runs the interrupt handler. When the interrupt handler returns, it goes back to StopCPU, so StopCPU returns and the OS checks for unblocked processes again. The hardware interrupt probably unblocked one of the processes. For example, if the interrupt was because the computer got a network packet, then now the process that was waiting for the packet is unblocked. If it was because the user pressed a key on the keyboard, then the process that was waiting for the key is unblocked, and so on.

So there are two main advantages to using blocking I/O instead of polling:

  • You don't waste CPU time that other processes could get.
  • If all processes are blocked (this is most of the time!) the CPU can save power and heat.

This is also how sleep works. There's a hardware timer that counts down and then sends an interrupt. When you do sleep(1), the OS sets the timer to one second, then blocks the process. When the interrupt comes in, it unblocks the process.

There's only one timer, but if more than one process is sleeping, the OS sets the timer to the one that wakes up first, and then when the interrupt comes in, it unblocks the first process and sets the timer for the next one. This technique is called a "timer queue".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top