Chapter 9
Scheduling Processes

How does the O/S select a process (thread) from the ready queue to execute? This depends to a large degree on our goals. Some possibilities:

The standard scheduling disciplines were all developed in the 1970's. However, they are based on some simplifying assumptions that were valid in the days of single-process, single CPU scheduling. They are not completely realistic for present multithreaded, multiprocessor systems. How best to relax these assumptions is still an open research problem.

Some of the standard disciplines:

Approximating Shortest Remaining Time First: How do we predict the amount of CPU time a job has remaining? We can't. So how do we approximate this knowledge? Use the past to predict the future.

Using Multilevel Feedback Queues to Approximate SRTF:

Adjusting Priorities:

In practice, CPU-bound jobs drop like a rock in priority, while I/O-bound jobs stay at a high priority.


Scheduler Example -- Windows NT 4.0

Windows 3.1 has a simple non-preemptive scheduler. Application programmers must insert an occasional Yield in their code to give the O/S a chance to take over.

Windows XP has a much more elaborate scheduling policy:

How does the scheduler choose the next thread to run?

Avoiding Starvation:

Bug (Feature?) in the Windows NT scheduler:

In NT a thread gets its quantum refreshed every time its thread or process priority is set. That means that the thread can reset its quantum by calling SetThreadPriority (without changing its priority) before its quantum expires. By continuing this practice, it can give itself an effectively infinite quantum!


Scheduler Example -- Unix

How priorities are computed:

P(j)(i) = Base(j) + CPU(j)(i-1)/2 + nice(j)

CPU(j)(i) = U(j)(i)/2 + CPU(j)(i-1)/2

P(j)(i) is the priority of process j at beginning of interval i.

Base(j) is the base priority of process j.

U(j)(i) is the processor utilization of process j in interval i.

CPU(j)(i) is the exponentially weighted average processor utilization by process j through interval i.

nice(j) is a user-controllable adjustment factor that can be used to lower a process's priority..