When scheduling processes, the kernel effectively gives every process a handful of counters. Every time a process gets scheduled onto the CPU, it gives up one of its counters. When deciding which process to schedule onto the CPU next, the kernel chooses the runnable process with the most counters. Eventually, the kernel will reach a state where all of the runnable processes have used up their counters. This is referred to as the end of a scheduling epoch, and at this point, the kernel starts all of the processes over again with a new handful of counters.
Notice that processes that are not in the runnable state never give up their counters. If, however, a sleeping process were to suddenly awaken (because something interesting happened) and be kicked into the runnable state, it would most likely have more counters than processes which had been running for a while, and would be quickly scheduled onto the CPU.
How does this relate to the values shown in the PRI column? Think of this column as a process’s number of counters, subtracted from 40. Therefore, processes with a lower priority (as listed by the top command) have the scheduling advantage. In the output above, the cat commands, which are constantly in the runnable state, are consuming their counters. The init process, however, who is sleeping quietly in the background, is not.
As mentioned above, every process also has a static value referred to as its niceness value. This value may range from -20 to 19 for any process, starting at 0 by default. How does a process’s niceness influence its scheduling? At the beginning of a scheduling epoch, you can think of the kernel subtracting a process’s niceness value from the number of counters the process is allocated. As a result, “nicer” processes (those with a higher niceness value) get fewer counters, and thus less time on the CPU, while “greedy” processes (those with a niceness value less than 0) get more counters and more time on the CPU. If a “nice” process is the only one running on the machine, however, it would get full access to the CPU.
Changing a Process’s Niceness
Suppose maxwell was about to run a physics simulation that would take several days to complete. By increasing the process’s niceness, the process would patiently wait if anyone else were running processes on the machine. If no one else were running processes, however, the physics simulation would have full access to the CPU.
There are several techniques by which maxwell could alter his process’s niceness value.
Using nice to Start a low Priority Command
The nice command is used to set a process’s niceness as the process is started. When maxwell starts his simulation (which is an executable in his home directory named ~/simulation), he makes it as nice as possible, with a value of +19. (He also places the process in the background. Again, don’t worry about that now. It will be discussed in a later Lesson.)
$ nice -19 ./simulation &
Notice that the syntax can be misleading. The token -19 should not be considered negative 19, but instead the numeric command-line switch 19. The user maxwell then again monitors processes using the top command. The first few processes listed are listed below.
1. As a convenience, the ps command decorates the process state with a “N”, to indicate the process has had its niceness value increased.
2. Because other cat commands are using the machine, maxwell’s simulation is only getting about 2.1% of the CPU.
As an additional subtlety, the number specified is the number to be added to the current shell’s niceness value. Since most shells run with a niceness of 0, this is seldom noticed. But if a shell were running with a niceness value of 10, the following command line would result in the simulation running with a niceness value of 15.
$ nice -5 ./simulation &
Using renice to Alter a Running Process
The renice command can be used to change the niceness of an already running process. Processes can be specified by process id, username, or group name, depending on which of the following command line switches are used.
|-p||interpret remaining arguments as process ID’s (the default)|
|-u||interpret remaining arguments as usernames.|
|-g||interpret remaining arguments as group ID’s.|
Suppose maxwell had already started his simulation, without altering its niceness value. The process is receiving large amounts of CPU time as shown below (58.9%).
$ ps -C simulation u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND maxwell 7348 58.9 0.1 3408 400 pts/5 R 01:29 0:50 simulation
The process has the default niceness value of 0.
$ ps -C simulation l F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND 0 515 7348 6064 25 0 3408 400 - R pts/5 0:51 simulation
He decides to be more polite to other people who might be using the machine, and uses the renice command to bump up the process’s niceness value. In the absence of any command line switches, the renice command expects a niceness value and a process ID as its two arguments.
$ renice 19 7347 7348: old priority 0, new priority 19
Notice the inconsistency in syntax. The renice command, unlike the nice command, does not expect the niceness value to be specified as a commandline switch, but as an argument. Infact, renice -19 7347 would be interpreted as a niceness value of -19. Further muddying the waters, the output of the renice command refers to the value as a priority, instead of a niceness. (as some of the related documentation does, as well).
Using top to Renice a Process
As mentioned in the previous unit, the top command uses the r key to renice a process. While monitoring processes with top, pressing r will open the following dialog above the list of processes.
PID to renice: 7347 Renice PID 7347 to value: 19
Making Processes Greedier
What if maxwell were more malicious in intent, and wanted to make his simulation greedier instead of nicer? Fortunately for other users on the machine, normal users cannot lower the niceness of a process. This has two implications.
1. Because processes start with a default niceness of 0, standard users cannot make “greedy” processes with negative niceness values.
2. Once a process has been made nice, it cannot be made “normal” again by normal users.
Suppose the administrator noticed that maxwell’s simulation was taking up excessive amounts of CPU time. She could use the renice command as root to bump up maxwell’s niceness, and maxwell could not restore it.