Você está na página 1de 72

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)

Você também pode gostar