3.4 Process Scheduling

When a ready queue contains several processes, the scheduler must determine which process should be assigned to a processor first. The scheduler maintains data structures that allow it to schedule the processes in an efficient manner. Each process is given a priority class and placed in a priority queue with other runnable processes with the same priority class. There are multiple priority queues, each representing a different priority class used by the system. These priority queues are stratified and placed in a dispatch array called the multilevel priority queue, illustrated in Figure 3-5. Each element in the array points to a priority queue. The scheduler assigns the process at the head of the nonempty highest priority queue to the processor.

Figure 3-5. The multilevel priority queue in which each entry of the dispatch array points to a ready queue of processes with the same priority level.

graphics/03fig05.gif

Priorities can be dynamic or static . Once a static priority of a process is set, it cannot be changed. Dynamic priorities can be changed. Processes of the highest priority can monopolize the use of the processor. If the priority of a process is dynamic, the initial priority can be adjusted to a more appropriate value. The process is placed in a priority queue that has a higher priority. A process monopolizing the processor can also be given a lower priority or other processes can be given a higher priority than that process. In the UNIX/Linux environments, the range of priority levels is from -20 to 19 . The higher the value, the lower the priority.

When assigning priority to a user process, what the process spends most of its time doing should be considered . Some processes are CPU intensive. CPU- intensive processes use the processor for the whole time slice. Some processes spend most of their time waiting for I/O or some other event to occur. When such a process is ready to use a processor, it should be given the processor immediately so it can make its next request for I/O. Processes that are interactive may require a high priority to ensure good response time. System processes have a higher priority than user processes.

3.4.1 Scheduling Policy

The processes are placed in a priority queue according to a scheduling policy. Two of the scheduling policies used by the UNIX/Linux systems are FIFO (First-In-First-Out) and round- robin (RR) policies. Figure 3-6(a) shows the FIFO scheduling policy. With a FIFO scheduling policy, processes are assigned a processor according to the arrival time in the queue. When a running process time slice has expired , it is placed at the head of its priority queue. When a sleeping process becomes runnable, the process is placed at the end of its priority queue. A process can make a system call and give up a processor to another process with the same priority level. The process will be placed at the end of its priority queue.

Figure 3-6. The behavior of the First-In-First-Out (FIFO) and round-robin (RR) scheduling policies. The FIFO scheduling policy assigns processes to the processor according to its arrival time in the queue. The process runs until completion. The RR scheduling policy assigns processes using FIFO scheduling but when the time slice runs out the process is placed at the back of the ready queue.

graphics/03fig06.gif

In a round-robin scheduling policy, all processes are considered equal. Figure 3-6(b) depicts the RR scheduling policy. RR scheduling is the same as FIFO scheduling with an exception: when the time slice expires , the process is placed at the back of the queue and the next process in the queue is assigned the processor.

3.4.2 Using the ps Utility

The ps utility generates a report that summarizes execution statistics for the current processes. This information can be used to monitor the status of current processes. Table 3-2 lists the common headers and the meaning of the output for the ps utility for the Solaris/Linux environments. In a multi-processor environment, the ps utility is quite useful to monitor the state, CPU and memory usage, processor utilized, priority, and start time of the current processes executing. Command options control which processes are listed and what information is displayed about each process. In the Solaris environment, by default (no command options used), information about processes with the same effective user id and controlling terminal of the calling invoker is displayed. In the Linux environment, by default, the processes with the same user id as the invoker are displayed. In both environments, the only information that will be displayed is PID , TTY , TIME and COMMAND . These are some of the options that control which processes are displayed:

-t term

List the processes associated with the terminal specified by term

-e

All current processes

-a

(Linux) All processes with tty terminal except the session leaders

 

(Solaris) Most frequently requested processes except group leaders and processes not associated with a terminal

-d

All current processes except session leaders

T

(Linux) All processes in this terminal

a

(Linux) All processes including those of other users

r

(Linux) Only running processes

Table 3-2. Common Headers Used for ps Utility in the Solaris/Linux Environments

Headers

Description

USER, UID

Username of process owner

PID

Process ID

PPID

Parent process ID

PGID

ID of process group leader

SID

ID of session leader

%CPU

Percentage of CPU time used by the process in the last minute

RSS

Amount of real RAM currently used by the process in k

%MEM

Percentage of real RAM used by the process in the last minute

SZ

Size of virtual memory of the process's data and stack in k or pages

WCHAN

Address of an event for which a process is sleeping

COMMAND CMD

Command name and arguments

TT, TTY

Process's controlling terminal

S, STAT

Current state of the process

TIME

Total CPU time used by the process (HH:MM:SS)

STIME, START

Time or date the process started

NI

Nice value of the process

PRI

Priority of the process

C, CP

Short-term CPU-use factor used by the scheduler to compute PRI

ADDR

Memory address of a process

LWP

ID of the lwp (thread)

NLWP

The number of lwps

Synopsis

 (Linux) ps -[Unix98 options]    [BSD-style options]    --[GNU-style long options (Solaris) ps [-aAdeflcjLPy] [-o format] [-t termlist][-u userlist]    [-G grouplist][-p proclist] [-g pgrplist] [-s sidlist] 

The following list contains some of the command options used to control the information displayed about the processes:

-f

full listings

-l

long format

-j

jobs format

Below is an example of using the ps utility in Solaris/Linux environments:

 ps -f 

This will display information about the default processes in each environment. Figure 3-7 shows the output in the Solaris environment. The command options can also be used in tandem. Figure 3-7 also shows the output of using -l and -f together in the Solaris environment:

 ps -lf 
Figure 3-7 Output of ps -f and ps -lf in the Solaris environment.
 //SOLARIS $ ps -f      UID   PID  PPID  C    STIME    TTY  TIME CMD  cameron  2214  2212  0 21:03:35 pts/12  0:00 -ksh  cameron  2396  2214  2 11:55:49 pts/12  0:01 nedit $ ps -lf F S     UID  PID  PPID  C  PRI NI     ADDR  SZ    WCHAN    STIME   TTY TIME  CMD 8 S cameron 2214  2212  0   51 20 70e80f00 230 70e80f6c 21:03:35 pts/12 0:00 -ksh 8 S cameron 2396  2214  1   53 24 70d747b8 843 70152aba 11:55:49 pts/12 0:01 nedit 

The l command option shows the additional headers: F , S , C , PRI , NI , ADDR , and WCHAN . The P command option will display the PSR header. Under this header is the number of the processor to which the process is assigned or bound.

Figure 3-8 shows the output of the ps utility using the Tux command options in the Linux environment. The %CPU , %MEM , and STAT information is displayed for the processes. In a multiprocessor environment, this information can be used to monitor which processes are dominating CPU and memory usage. The STAT header shows the state or status of the process. Table 3-3 lists how the status is encoded and their meanings. The STAT header can reveal additional information about the status of the process:

D

(BSD) Disk wait

P

(BSD) Page wait

X

(System V) Growing: waiting for memory

W

(BSD) Swapped out

K

(AIX) Available kernel process

N

(BSD) Niced: execution priority lowered

>

(BSD) Niced: execution priority artificially raised

<

(Linux) High priority process

L

(Linux) Pages are locked in memory

Figure 3-8 Output of ps Tux in the Linux environment.
 //Linux [tdhughes@colony]$ ps Tux USER       PID %CPU %MEM   VSZ  RSS   TTY  STAT   START  TIME COMMAND tdhughes 19259  0.0  0.1  2448 1356  pts/4    S   20:29  0:00 -bash tdhughes 19334  0.0  0.0  1732  860  pts/4    S   20:33  0:00 /home/tdhughes/pv tdhughes 19336  0.0  0.0  1928  780  pts/4    S   20:33  0:00 /home/tdhughes/pv tdhughes 19337 18.0  2.4 26872 24856 pts/4    R   20:33  0:47 /home/tdhughes/pv tdhughes 19338 18.0  2.3 26872 24696 pts/4    R   20:33  0:47 /home/tdhughes/pv tdhughes 19341 17.9  2.3 26872 24556 pts/4    R   20:33  0:47 /home/tdhughes/pv tdhughes 19400  0.0  0.0  2544  692  pts/4    R   20:38  0:00 ps Tux tdhughes 19401  0.0  0.1  2448 1356  pts/4    R   20:38  0:00 -bash 

These codes will precede the status codes. If an N precedes the status, this means that the process is running at a lower priority level. If a process has a status SW< , this means the process is sleep, swapped out, and has a high priority level.

3.4.3 Setting and Returning the Process Priority

The priority level of a process can be changed by using the nice() function. Each process has a nice value that is used to calculate the priority level of the calling process. A process inherits the priority of the process that created it. The priority of a process can lowered by raising its nice value. Only superuser and kernel processes can raise their priority levels.

Synopsis

 #include <unistd.h> int nice(int incr); 

A low nice value raises the priority level of the process. The incr parameter is the value added to the current nice value of the calling process. The incr can be negative or positive. The nice value is a non-negative number. A positive incr value will raise the nice value, therefore lowering the priority level. A negative incr value will lower the nice value, therefore raising the priority level. If the incr value raises the nice value above or below its limits, the nice value of the process will be set to the highest or lowest limit accordingly . If successful, the nice() function will return the new nice value of the process. If unsuccessful , the function will return -1 and the nice value is not changed.

Synopsis

 #include <sys/resource.h> int getpriority(int which, id_t who); int setpriority(int which, id_t who, int value); 

The setpriority() function sets the nice value for a process, process group, or user. The getpriority() returns the priority of a process, process group, or user. Example 3.1 shows the syntax to the functions setpriority() and getpriority() to set and return the nice value of the current process.

Example 3.1 Using setpriority() and getpriority() .
 #include <sys/resource.h> //... id_t pid = 0; int which  = PRIO_PROCESS; int value = 10; int nice_value; int ret; nice_value = getpriority(which,pid); if(nice_value < value) {     ret = setpriority(which,pid,value); } //... 

In Example 3.1, the priority of the calling process is being returned and set. If the calling process's nice value is < 10, the nice value of the process is set to 10 . The target process is determined by the values stored in the which and who parameters. The which parameter can specify a process, process group, or user. It can have the following values:

PRIO_PROCESS

Indicates a process

PRIO_PGRP

Indicates a process group

PRIO_USER

Indicates a user

Depending on the value of which , the who parameter is the id number of a process, process group, or effective user. In Example 3.1, which is assigned PRIO_PROCESS . A value for who indicates the current process, process group, or user. In Example 3.1, the who is set to , indicating the current process. The value parameter for setpriority() shall be the new nice value for the specified process, process group, or user. The range of nice value in the Linux environment is -20 to 19 . In Example 3.1, the value of nice is set to 10 if the current nice value is less than 10 . Unlike the function nice() , the value passed to setpriority() is the actual value of nice and not an offset to be added to the current nice value.

In a process with multiple threads, the modification of the priority will affect the priority of all the threads in that process. If successful, getpriority() will return the nice value of the specified process. If successful, setpriority() will return . If unsuccessful, both functions will return -1 . The return value -1 is a legitimate nice value for a process. To determine if an error has occurred, check the external variable errno .



Parallel and Distributed Programming Using C++
Parallel and Distributed Programming Using C++
ISBN: 0131013769
EAN: 2147483647
Year: 2002
Pages: 133

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net