Firstly you need to understand that Windows allocates processor time to threads, not to processes or programs. Each time the scheduler is called upon to reschedule which threads are running, it looks at only the set of threads which are runnable - not blocked waiting for some event to occur. GUI threads are typically waiting for the user to press a key or move the mouse over the window, or for some other window message to arrive. This can also be a timer event created by the SetTimer function. Whenever you call a synchronous I/O function such as ReadFile, if the data isn't already buffered in the system's cache, the OS begins a read from the disk, then blocks the thread until the data arrives, and it's not runnable. If you use the WaitForSingleObject or {Msg}WaitForMultipleObjects{Ex} functions, your thread blocks until one of the conditions is satisfied. Blocking for I/O can happen without any specific command from the programmer if the program references data that isn't currently in memory (whether to be read in from the original program files or from the page file). The scheduler considers the set of runnable threads in priority order, from highest priority (31) to lowest (0). It only considers threads from the highest priority at which there are runnable threads, unless there are fewer threads at the highest priority than there are processors, in which case it will consider threads at the next lowest priority level which has runnable threads. This means that if a high priority thread never blocks (and therefore stops being runnable), it can prevent lower priority threads from getting CPU time. Best practice is to simply use the Normal priority, the default. The scheduler maintains a queue of threads at each priority level, and simply (if all default values are used) assigns the first N threads in the queue to each of the N logical processors in the system. The scheduler is invoked when one of three things happen: a running thread's quantum (time permitted to run) expires; a running thread blocks; some other event in the system causes a higher-priority thread to unblock. Windows raises priorities for some unblocking events which cause a thread to temporarily have a higher priority, which increases responsiveness. This is complicated by affinity (where a thread can be prevented from running on certain logical processors), and by the fact that Windows allocates an ideal processor for each thread, and remembers the last process