CPU Scheduling
Contents
Basic
Concepts
Scheduling Criteria
Scheduling Algorithms
Process Creation
A process may create several new processes, via a create-process system
call during the course of execution.
Generally, process identified and managed via a process identifier (pid)
The creating process is called parent process and the new processes are
called children of that process, children processes, in turn create other
processes, forming a tree of processes.
Resource sharing
Parent and children share all resources
Children share subset of parents resources
Parent and child share no resources
Execution
Parent and children execute concurrently
Parent waits until children terminate
Process Creation (Cont)
Address space
Child duplicate of parent
Child has a program loaded into it
UNIX examples
fork system call creates new process
Each process is identified by its process identifier ( a unique
integer)
The new process consists a copy of the address space of the
original process.
Both process continues execution after fork system call.
The return code for the fork system call is zero for the new
process whereas the process identifier of the child is returned
to the parent.
Fork() system call
System call fork() is used to create processes.
It takes no arguments and returns a process ID.
The purpose of fork() is to create a new process, which becomes
the child process of the caller.
After a new child process is created, both processes will execute the next
instruction following the fork() system call.
Therefore, we have to distinguish the parent from the child. This can be
done by testing the returned value of fork():
If fork() returns a negative value, the creation of a child process was
unsuccessful.
fork() returns a zero to the newly created child process.
fork() returns a positive value, the process ID of the child process, to the
parent.
Simple program of fork
#include<stdio.h>
Void main()
{
int pid;
printf(Hello\n);
pid =fork();
if(pid<0){
printf(child not created);}
else if(pid==0) {
printf(I am child process\n);}
else {
printf(I am parent process\n);}
}
Your Main Program
with fork() system
call
fork()
Copy 1:
Parent with all the code
after fork().
Parent process will
execute the next
instruction following the
fork() system call
Copy 2:
Child with all the
code after fork().
Child process will
execute the next
instruction
following the
fork() system call
pid = fork();
returns pid of
the child which
is non zero
pid = fork();
returns pid =0
in the child
A tree of processes on a Unix
Process Termination
Process executes last statement and asks the operating
system to delete it (exit)
Output data from child to parent (via wait)
Process resources are deallocated by operating system
Parent may terminate execution of children processes (abort)
Child has exceeded allocated resources
Task assigned to child is no longer required
If parent is exiting
Some operating system do not allow child to continue if
its parent terminates
All children terminated - cascading termination
C Program Examples
Getpid() and getppid()
getpid() and getppid() return a process's
id and parent process's id numbers,
respectively.
System Call: int getpid()
int getppid()
#include <stdio.h>
main()
{
int pid;
printf("I'm the original process with PID %d and PPID %d.\n", getpid(), getppid());
pid=fork();
/* Duplicate. Child and parent continue from here.*/
if (pid!=0)
/* pid is non-zero, so I must be the parent */
{
printf("I'm the parent process with PID %d and PPID %d.\n", getpid(),
getppid());
printf("My child's PID is %d.\n", pid);
}
else
/* pid is zero, so I must be the child. */
{
printf("I'm the child process with PID %d and PPID %d.\n", getpid(),
getppid());
}
printf("PID %d terminates.\n",getpid()); /* Both processes execute this */
}
Orphan Processes
If a parent dies before its child, the child is
automatically adopted by the original "init"
process, PID 1.
By inserting a sleep statement into the
child's code, the parent process
terminates before the child.
Orphan Processes
#include <stdio.h>
main()
{
int pid;
printf("I'm the original process with PID %d and PPID %d.\n", getpid(), getppid());
pid=fork();
/* Duplicate. Child and parent continue from here.*/
if (pid!=0)
/* Branch based on return value from fork() */
{
/* pid is non-zero, so I must be the parent */
printf("I'm the parent process with PID %d and PPID %d.\n", getpid(),
getppid());
printf("My child's PID is %d.\n", pid);
}
else
{
/* pid is zero, so I must be the child. */
sleep(50);
/*Make sure that the parent terminates first. */
printf("I'm the child process with PID %d and PPID %d.\n", getpid(),
getppid());
}
printf("PID %d terminates.\n",getpid());
/* Both processes execute this */
}
Waiting For A Child: wait()
A parent process may wait for one of its children to terminate
and then accept its child's termination code by executing wait():
System Call: int wait(int *status)
wait() causes a process to suspend until one of its children
terminates.
A successful call to wait() returns the pid of the child that
terminated
If a process executes a wait() and has no children, wait()
returns immediately with -1.
Program using wait()
#include <stdio.h>
main()
{
int pid, status, childPid;
printf("I'm the parent process and my PID is %d\n", getpid());
pid=fork(); /* Duplicate.*/
if (pid!=0) /* Branch based on return value from fork() */
{
printf("I'm the parent process with PID %d and PPID %d.\n", getpid(), getppid());
childPid=wait(&status); /* wait for a child to terminate */
printf("A child with PID %d terminated with exit code %d\n", pid, status>>8);
else
{
printf("I'm the child process with PID %d and PPID %d.\n", getpid(), getppid());
exit(42); /* Exit with a random number. */
}
printf("PID %d terminates.\n",getpid());
}
Output
I'm the parent process and my PID is 13464
I'm the child process with PID 13465 and PPID
13464.
I'm the parent process with PID 13464 and
PPID 13409
A child with PID 13465 terminated with exit
code 42
PID 13465 terminates
System call exit()
System Call: int exit(int status)
exit() closes all of a process's file descriptors,
deallocates its code, data, and stack, and then
terminates the process.
When a child process terminates, it sends its
parent a SIGCHLD signal and waits for its
termination code status to be accepted.
If a child terminates & parent is not calling wait,
i.e. , the process is waiting for its parent to
accept its return code, it is called a zombie
process.
exit()
#include <stdio.h>
main()
{
printf("I'm going to exit with return code 42\n");
exit(42);
}
OutputI'm going to exit with return code 42
Zombie process
#include <stdio.h>
main()
{
int pid;
pid=fork(); /* Duplicate */
if (pid!=0) /* Branch based on return value from fork() */
{
while (1) /* never terminate, and never execute a wait() */
sleep(1000);
}
else
{
exit(42); /* Exit with a random number */
}
}
Zombie process
$ zombie.exe & ... execute the program in the background.
[1] 13545
$ ps
PID TT STAT TIME COMMAND
13535 p2 s 0:00 -ksh(ksh) ...the shell
13545 p2 s 0:00 zombie.exe...the parent process
13536 p2 z 0:00 <defunct> ...the zombie child process
13537 p2 R 0:00 ps
$ kill 13545
... kill the parent process.
[1] Terminated zombie.exe
$ ps
... notice the zombie is gone now.
PID TT STAT TIME COMMAND1
3535 p2 s 0:00 -csh(csh)
13548 p2 R 0:00 ps
Almost all processes alternate between two
states in a continuingcycle,
A CPU burst of performing calculations,
and
An I/O burst, waiting for data transfer in
or out of the system.
CPU-I/O Burst Cycle
Process execution begins with a CPU burst.
This is followed by an I/O burst.
The last CPU burst will end with a system
request to terminate execution.
An I/O bound process have many short CPU
bursts and long I/O bursts.
A CPU bound process have very long CPU
burst and short I/O burst.
CPU Scheduling
Determining
which processes run when there are
multiple runnable processes
scheduling system allows one process to
use the CPU while another is waiting for I/O,
thereby making full use of otherwise lost CPU
cycles.
Objective of CPU scheduling is to maximize
CPU utilization
The challenge is to make the overall system
as "efficient" and "fair" as possible.
Assumption: CPU Bursts
Execution model: programs alternate between bursts of CPU and I/O
Program typically uses the CPU for some period of time, then does I/O, then uses CPU
again
Each scheduling decision is about which job to give to the CPU for use by its next CPU
burst
With timeslicing, thread may be forced to give up CPU before finishing current CPU burst.
CPU Scheduler (Short-term Scheduler)
CPU scheduling decisions may take place when a process:
1. Switches from running to waiting state
2. Switches from running to ready state
3. Switches from waiting to ready
4. Terminates
5. A new process joins new state.
2
Preemptive vs Nonpreemtive Scheduling
In preemptive scheduling we preempt the currently
executing process.
In non preemptive we allow the current process to finish
its CPU burst time.
Dispatcher
Dispatcher module gives control of the CPU to the
process selected by the short-term scheduler; this
involves:
switching context
switching to user mode
jumping to the proper location in the user
program to restart that program
Dispatchlatency time it takes for the dispatcher
to stop one process and start another running
The dispatcher should be as fast as possible.
Scheduling Criteria
CPU utilization Percentage of time that the CPU is doing useful work
Throughput Number of processes completed per unit time. May range
from 10 / second to 1 / hour depending on the specific processes.
Turnaround time Time required for a particular process to complete,
from submission time to completion.
It is sum of periods spent waiting to get into memory, waiting in the
ready queue, execution on the CPU, and doing I/O
Waiting time amount of time a process has been waiting in the ready
queue to get on the CPU
Response time amount of time it takes from when a request was
submitted until the first response is produced, not output (for timesharing environment)
Optimization Criteria
Max CPU utilization
Max throughput
Min turnaround time
Min waiting time
Min response time
Most of the time we are interested in optimizing the
average Value.
First-Come, First-Served
(FCFS) Scheduling
Simplest CPU-scheduling algorithm
The process that requests the CPU first is allocated
the CPU first.
Key concept is Allocate the CPU in the order in
which the processes arrive.
Ready queue is managed as FIFO.
The process occupying the front of the queue is allocated
the CPU.
The process that arrives is put at the rear end of ready
queue.
Algorithm is non-preemptive.
FCFS Scheduling Example
suppose the scheduler is given 4 tasks, A, B, C and D. Each task requires a
certain number of time units to complete.
Task
Time units
A
The FCFS schedulers Gantt chart for these tasks would be:
The OS incurs some overhead each time it switches between processes due
to context switching. We will call this overhead cs.
CPUUtilization -26/(26+3cs)
Turnaroundtime - (8+12+21+26+6cs)/4 = 16.5 ignoring cs
Waiting-(0+8+12+21+6cs)/4=10.25ignoringcs
Throughput-4/(26+3cs)
Response-(0+8+cs+12+2cs+21+3cs)/4=10.25ignoringcs
First-Come, First-Served (FCFS)
SchedulingProcess Burst Time
P1
P2
P3
24
3
3
Suppose that the processes arrive in the order: P1 , P2 , P3
First-Come, First-Served
(FCFS) Scheduling
The Gantt Chart for the schedule is:
P1
0
P2
24
P3
27
30
Waiting time for P1 = 0; P2 = 24+cs; P3= 27+ 2cs
Average waiting time: (0 + 24 + 27 + 3cs)/3 =
17(ignorong cs)
FCFS Scheduling (Cont.)
Suppose that the processes arrive in the order
P2 , P3 , P1
The Gantt chart for the schedule is:
P2
0
P3
3
P1
6
Waiting time for P1= 6 +2cs;P2 = 0;P3=3 +cs
Average waiting time: (6 + 0 + 3)/3 = 3
Much better than previous case
30
Convoyeffect short process behind long process
First-Come, First-Served
(FCFS) Scheduling
Advantages
Simple to understand and code.
Suitable for Batch systems
Disadvantages
Waiting time can be large if short requests wait
behind the long ones.
Not suitable for time sharing systems.
A proper mix of jobs(I/O based and CPU based
jobs) is needed to achieve good results from
FCFS scheduling
Shortest-Job-First (SJF)
Scheduling
Key Concept of this algorithm is CPU is allocated to the process with
least CPU-burst time
Associate with each process the length of its next CPU burst. Use these
lengths to schedule the process with the shortest time
If there are two processes with same CPU burst, the one which arrived
first, will be taken up first by the CPU.
Two schemes:
nonpreemptive once CPU given to the process it cannot be
preempted until completes its CPU burst
Preemptive(SRTF) if a new process arrives with CPU burst length
less than remaining time of current executing process, preempt. This
scheme is know as the Shortest-Remaining-Time-First (SRTF)
SJF is optimal gives minimum average waiting time for a given set of
processes
Shortest-Job-First (SJF)
Scheduling Example 1
Suppose the scheduler is given 4 tasks, A, B, C and D. Each task requires a certain
number of time units to complete.
Task
Time units
A
The SJF Gantt Chart would be:
CPUUtilization -26/(26+3cs)
AvgTurnaroundtime-(4+9+cs+17+2cs+26+3cs)/4 = 14 ignoring cs
AvgWaiting-(0+4+cs+9+2cs+17+3cs)/4 = 7.5 ignoring cs
Throughput-4/(26 + 3cs)
AvgResponse-(0+4+cs+9+2cs+17+3cs)/4 = 7.5 ignoring cs
By comparison, if we were using the FCFS schedulingscheme, the average waiting
time would be 10.25 milliseconds.
Example 2: Non-Preemptive
SJF
Process Arrival Time
P1
0.0
P2
2.0
P3
4.0
P4
5.0
P1
0
P3
7
Burst Time
7
4
1
4
P2
P4
12
16
SJF (non-preemptive)
Average waiting time = (0 + 6 + 3 + 7)/4 = 4(ignoring cs)
Example 3: Preemptive
SJF(SJRT)
Process
Arrival Time
Burst Time
P1
0.0
P2
2.0
P3
4.0
P4
5.0
P1
0
P2
2
P3
4
P2
5
P4
7
P1
11
16
SJF (preemptive)
Average waiting time = (9 + 1 + 0 +2)/4 = 3 (ignoring cs)
Shortest-Job-First (SJR)
Scheduling
Advantage
It is considered as an optimal algorithm as it gives the minimum
average waiting time
Moving a short burst ahead of a long one reduces wait time of short
process more than it lengthens wait time of long one.
Disadvantage
The problem is to know the length of time for which CPU is
needed by a process. A prediction formula can be used to predict
the amount of time for which CPU may be required by a process.
Problem of starvation
Starvation occurs when a large process never gets CPU to run if
shorter processes keep entering the queue.
Comparison of SJF with FCFS
What if all jobs are the same length?
What if all jobs have varying length?
Comparison of SJF with FCFS
What if all jobs are the same length?
SJF becomes the same as FCFS (i.e. FCFS is the
best we can do)
What if all jobs have varying length?
SJRTF : short jobs are not stuck behind long ones
Priority Scheduling
A priority number (integer) is associated with each process.
The CPU is allocated to the process with the highest priority whereas lower
priority job can be made to wait.
(smallest integer highest priority)
Preemptive(if a higher priority process enters, it receives the CPU
immediately)
nonpreemptive(higher priority processes must wait until the current
process finishes; then, the highest priority ready process is selected)
SJF is a priority scheduling where priority is the inverse of the predicted next
CPU burst time
The main problem with priority scheduling is starvation, that is, low priority
processes may never execute
A solution is aging; as time progresses, the priority of a process in the ready
queue is increased
Priority Scheduling Example
Round Robin (RR)
This algorithm is designed especially for time-sharing
systems.
It is similar to FCFS scheduling, but preemption is
added to switch between processes.
Each process gets a small unit of CPU time (time
quantum or time slice), usually 10-100 milliseconds.
After this time has elapsed, the process is preempted
and added to the end of the ready queue.
This algorithm is purely preemptive.
Round Robin (RR)
Round Robin (RR) Example
Example of RR with Time
Quantum = 20
Process
Burst Time
P1
53
P2
P3
68
P4
17
24
Example of RR with Time
Quantum
= 20
Process Burst Time
Waiting time
P1
P2
P3
P4
81
20
94
97
The Gantt chart is:
P1
53
17
68
24
P2
20
37
P3
P4
57
P1
77
P3
P4
P1
P3
P3
97 117 121 134 154 162
Average waiting time =73
Average turn-around time = 134 + 37 + 162 + 121) / 4 = 113.5
Average turn around time in SJF=80
Typically, higher average turnaround than SJF, but better response
Time Quantum and Context
Switch Time
Round Robin (RR)
The
performance of this algorithm is based
on
Size of time quantum
Number of context switches.
Turnaround Time Varies With The Time Quantum
As can be seen from this graph, the average turnaround time of a set of processes
does not necessarily improve as the time quantum size increases. In general, the
averageturnaroundtimecanbeimprovedifmostprocessesfinishtheirnextCPUburst
inasingletimequantum.
Round Robin (RR)
Advantages: simple, works for interactive Systems
RR makes the assumption that all processes are equally important
Disadvantages: if quantum is too small, too much time
wasted in context switching; if too large (i.e. longer than
mean CPU burst), approaches FCFS.
Rule of thumb: Choose quantum so that large majority
(80 90%) of jobs finish CPU burst in one quantum
Multilevel Queue Scheduling
Multi-level queue scheduling is used when processes can
be classified into groups
For example, foreground (interactive) processes and
background (batch) processes
The two types of processes have different responsetime requirements and so may have different
scheduling needs
Also,
foreground processes may have priority
(externally defined) over background processes
Multilevel Queue Scheduling
Ready queue is partitioned into several separate queues.
The processes are permanently assigned to one queue,
based on some property (memory size, process priority or
process type) of the process.
Each queue has its own scheduling algorithm
foreground RR
background FCFS/SJF
Scheduling must be done between the queues
Fixed priority scheduling; (i.e., serve all from foreground
then from background). Possibility of starvation.
Time slice each queue gets a certain amount of CPU
time which it can schedule amongst its processes; i.e.,
80% to foreground in RR, 20% to background in FCFS
Multilevel Queue Scheduling
One example of a multi-level queue are the five queues shown below
Each queue has absolute priority over lower priority queues
For example, no process in the batch queue can run unless the queues
above it are empty
However, this can result in starvation for the processes in the lower
priority queues
Multilevel Queue Scheduling
Assume there are 2 queues:- Q1(using RR scheduling with
quantum =8) for foreground processes and Q2(using FCFS
scheduling) for background processes. Consider following
processes arriving in the system
Process
P1
P2
P3
P4
Burst time
12
8
20
7
Type
FG
BG
FG
BG
Calculate average waiting time assuming that processes in Q1 will
be executed first.(Fixed priority scheduling)
Multilevel Queue Scheduling
Process
P1
P2
P3
P4
P1
Q1
Burst time
12
8
20
7
16
P3
Q1
P1
Q1
20
P3
Q1
Type
FG
BG
FG
BG
28
P3
Q1
32
P2
Q2
40
47
P4
Q2
Waiting time of P1=(20-12) =8
Waiting time of P2 = (40-8)=32
Waiting time of P4 =(47-7)=40
Waiting time of P3 = (32-20)= 12
Average waiting time = (8 + 32 + 40 + 12)/4=23
Multilevel Queue Scheduling
Disadvantage
It is inflexible as the process can never change
their queues
Starvation
Multilevel Feedback Queue Scheduling
Enhancement of Multilevel Queue scheduling
A process can move between the various queues
The idea is to separate processes with different CPU-burst
characteristics
Aging can be implemented this way
Multilevel-feedback-queue scheduler defined by the following
parameters:
number of queues
scheduling algorithms for each queue
method used to determine when to upgrade a process
method used to determine when to demote a process
method used to determine which queue a process will enter
when that process needs service
Example of Multilevel Feedback Queue
Scheduling
A new job enters queue Q1which is servedRRwithquantum8ms. When it gains
CPU, job receives 8 milliseconds. If it does not finish in 8 milliseconds, job is
moved to queue Q2.
At Q2 job is again served RR and receives 16 additional milliseconds. If it still
does not complete, it is preempted and moved to queue Q3.
Preemptive Scheduling. If a process arrives in Q1, then processes in Q2 and Q3
will stop its execution
Multilevel Feedback Queues
Consider the following set of processes:
Processes
Arrival time
P1
0
P2
12
P3
28
P4
36
P5
46
Compute Average waiting time?
Burst time
17
25
8
32
18
Multilevel Feedback Queues
Advantages
It allows a process to move between queues. This is fair for I/O bound
processes, they do not have to wait too long.
Aging prevents starvation.
More flexible
Disadvantages
Moving of processes around queues produces more CPU overheads.
Very complex algorithm
Multiple-Processor Scheduling
More complicated,
As now there is more than one CPU which must be kept busy
and in effective use at all times.
Multi-processor systems may be
heterogeneous, ( different kinds of CPUs ),
or homogenous, ( all the same kind of CPU ).
Even in the latter case there may be special scheduling
constraints, such as devices which are connected via a private
bus to only one of the CPUs.
Issues in multiple-processor
scheduling
Scheduling on a multiprocessor involves
interrelated issues:
The assignment of processes to processors
The use of multiprogramming on individual
processors
Assignment of processes to processors
The simplest scheduling approach is to treat the processors as a
pooled resource and assign processes to processors on demand.
Two issues:
Static assignment: a process is permanently assigned to one
processor from activation until its completion. A dedicated short-term
queue is maintained for each processor.
Advantages: less overhead in the scheduling.
Disadvantages: one processor can be idle, with an empty queue,
while another processor has a backlog.
Dynamic assignment: All processes go into one global queue and
are scheduled to any available processor. Thus, over the life of a
process, the process may be executed on different processors at
different times.
Advantages: better processor utilization.
Disadvantages: inefficient use of cache memory,
more difficult for the processors to communicate.
Master/slave architecture: key kernel functions of the operating
system always run on a particular processor. The master is responsible
for scheduling jobs.
Advantages:
simple approach, requires little enhancement to a uniprocessor
multiprogramming operating system
Disadvantages:
Approaches
to Multiple-Processor
a failure of the master brings down the whole system,
the master can become a performance bottleneck.
Scheduling
Peer architecture: the operating system can execute on any
processor, and each processor does self-scheduling from the pool of
available processes.
Problems: the operating system becomes complicated
Techniques must be employed to resolve and synchronize competing
claims to resources.
Processor Affinity
Try to keep a process on the same processor till last
time, because of Geographical Locality (Moving the
process to another CPU causes cache misses)
Processors contain cache memory, which speeds up
repeated accesses to the same memory locations.
If a process were to switch from one processor to
another each time it got a time slice, the data in the
cache ( for that process ) would have to be invalidated
and re-loaded from main memory, thereby obviating the
benefit of the cache.
Soft affinity
The process maymoveto another processor
Hard affinity
The process muststayon the same processor
Processor Affinity
Main memory architecture can also affect process affinity, if particular CPUs have
faster access to memory on the same chip or board than to other memory loaded
elsewhere. ( Non-Uniform Memory Access, NUMA. ) As shown below, if a process
has an affinity for a particular CPU, then it should preferentially be assigned memory
storage in "local" fast access areas.
Load Balancing
Keep the workload evenly distributed over the processors so that one
processor won't be sitting idle while another is overloaded.
Systems using a common ready queue are naturally self-balancing, and
do not need any special handling. Most systems, however, maintain
separate ready queues for each processor.
Balancing can be achieved through either push migration or pull
migration:
Push migration involves a separate process that runs periodically, ( e.g.
every 200 milliseconds ), and moves processes from heavily loaded
processors onto less loaded ones.
Pull migration involves idle processors taking processes from the ready
queues of other processors.
Push and pull migration are not mutually exclusive.
Note that moving processes from processor to processor to achieve load
balancing works against the principle of processor affinity, and if not
carefully managed, the savings gained by balancing the system can be
lost in rebuilding caches. One option is to only allow migration when
imbalance surpasses a given threshold.
Find
out about LINUX scheduling algorithm
How are process priorities set in LINUX?
Explore some energy-aware scheduling
algorithm
References
Chapter
5 of A.Silberschatz, P.Galvin, G.
Gagne, Operating systems concepts Willey
international company (8th edition)