If I have an empty while loop in my code such as:
while(true);
It will drive the processor usage up to about 25%. However if I do the followin
An empty loop isn't actually empty. A loop in itself is at least a comparison and a jump back to the comparison. Modern CPUs can do millions of these operations per second.
The sleep statement in the second loop relinquishes control to the operating system for at least 1 millisecond. In this state, the application is effectively halted and does not continue processing. The result of halting for x amount of time reduces the number of comparisons, and hence the % of cpu clock cycles the cpu can execute per second.
Concerning the 25%, Intel processors that support Hyperthreading or multi core processors might taint the performance statistics. The empty loop is effectively topping off at least one processor core.
Back in the day when multicore CPUs didn't exist, the users did have the need for multi processing/tasking. There are a couple of ways the illusion of running multiple processes at the same time was achieved.
One way was to design application in such a way that they needed to relinquish control to the system ever so often, as to let other processes run for a while. This was the case in the old Windows versions. If a given application was badly designed so that it didn't relinquish control, or got stuck in an endless loop, your entire PC effectively froze up.
Needless to say this wasn't the best way, and it was replaced by preemptive multitasking. Here a Programmable Interrupt Timer is instructed to interrupt the running process at a given interval to execute some scheduler code that lets the other processes have a go.