Process Scheduling
Like many dialects of UNIX,
the process scheduler is a function inside the kernel, not a
separate process. Actually, it’s better to say that process scheduling is done by two functions
working together, both of which are a part of sched.c. The first function is schedule(), which does
the actual scheduling. The other is do_timer(), which is called at different times and whose
function is to update the times of each process. Essentially, this is used to keep track of how long
each process has been running, how long it has had the processors, how long it has been in user
mode, how long it has been in kernel
mode, etc.
In the section on operating system basics,
I mentioned that each process gets a time slice
that’s 1/100th of a second long. At the end of each time slice,
the do_timer() function is called and priorities are recalculated. Each time a system call
returns to user mode, do_timer() is
also called to update the times.
Scheduling
processes is not as easy as finding the process that has been waiting the longest. Some operating
systems do this kind of scheduling, which is referred to as “round-robin.” The processes
could be thought of as sitting in a circle. The scheduling algorithm could then be though of as a
pointer that moves around the circle, getting to each process in turn. The Linux scheduler does a
modified version of round-robin scheduling, however, so that processes with a higher priority get to run more often and longer.
Linux also allows you to be nice to your fellow processes. If you feel
that your work is not as important as someone else’s, you might want to consider being nice to them.
This is done with the nice command, the syntax of which is
nice <nice_value> <command>
For example, if you wanted to run the date command with a lower priority, you could run it like this:
nice -10 date
This decreases the start priority of the date
command by 10. Nice values range from 19 (lowest priority) to -20 (highest priority).
Note that only root can increase a process’ priority, that is, use a negative nice
value. The nice value
only affects running processes, but child processes inherit the nice value of
their parent. By default, processes that users start have a nice value
of 20.
The numeric
value calculated for the priority is the opposite of what we normally think of as priority. A
better way of thinking about it is like the pull-down number tickets you get at the ice cream
store. The lower the number, the sooner you’ll be served. So it is for processes as well.
Although the nice command only works when you start a process, you can change
the nice value on a running process by using the renice command. It uses
the same priorities as nice, but is used on processes that are already
running. It can take the -p option for a specific PID, the
-g option for a process group, or -u for the
processes belonging to a specific user.
The number of times the clock interrupts per second, and therefore the numbers of times the
priority is recalculated, is defined by the HZ system variable.
This is defined by default to be 100HZ, or 100
times a second. However, we are assuming that the priorities are only calculated once a second
instead of 100 times.