0% found this document useful (0 votes)
84 views

Pos Notes Unit-2

Uploaded by

sravs22
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

Pos Notes Unit-2

Uploaded by

sravs22
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 37

GOKARAJU RANGARAJU INSTITUTE OF ENGINEERING AND TECHNOLOGY

PRINCIPLES OF OPERATING SYSTEMS

Course Code:GR18A2061 L/T/P/C: 3/0/0/3


II Year II Semester

UNIT-II:
Process Management – Process concept, process scheduling, operations, Inter process
Communication, Multi Thread programming models. Process scheduling criteria and
algorithms, and their evaluation.

2.1 Process Concept

 A process is an instance of a program in execution.


 Batch systems work in terms of "jobs". Many modern process concepts are still
expressed in terms of jobs, ( e.g. job scheduling ), and the two terms are often
used interchangeably.

2.1.1 The Process

 Process memory is divided into four sections

o The text section comprises the compiled program code,


read in from non-volatile storage when the program is launched.
o The data section stores global and static variables,
allocated and initialized prior to executing main.
o The heap is used for dynamic memory allocation, and is
managed via calls to new, delete, malloc, free, etc.
o The stack is used for local variables. Space on the stack is
reserved for local variables when they are declared ( at function
entrance or elsewhere, depending on the language ), and the space is
freed up when the variables go out of scope. Note that the stack is also
used for function return values, and the exact mechanisms of stack
management may be language specific.
o Note that the stack and the heap start at opposite ends of the process's
free space and grow towards each other. If they should ever meet, then
either a stack overflow error will occur, or else a call to new or malloc
will fail due to insufficient memory available.
 When processes are swapped out of memory and later restored,
additional information must also be stored and restored. Key among
them are the program counter and the value of all program registers.

Figure 2.1 - A process in memory

2.1.2 Process State

 Processes may be in one of 5 states, as shown in Figure 2.2 below.

o New - The process is in the stage of being created.


o Ready - The process has all the resources available that it
needs to run, but the CPU is not currently working on this process's
instructions.
o Running - The CPU is working on this process's instructions.
o Waiting - The process cannot run at the moment, because it is waiting
for some resource to become available or for some event to occur. For
example the process may be waiting for keyboard input, disk access
request, inter-process messages, a timer to go off, or a child process to
finish.
o Terminated - The process has completed.
 The load average reported by the "w" command indicate the average
number of processes in the "Ready" state over the last 1, 5, and 15
minutes, i.e. processes who have everything they need to run but cannot
because the CPU is busy doing something else.
 Some systems may have other states besides the ones listed here.
Figure 3.2 - Diagram of process state

3.1.3 Process Control Block

For each process there is a Process Control Block, PCB, which stores the
following ( types of ) process-specific information, as illustrated in
Figure 3.1. ( Specific details may vary from system to system. )

 Process State - Running, waiting, etc., as discussed above.


 Process ID, and parent process ID.
 CPU registers and Program Counter - These need to be saved and
restored when swapping processes in and out of the CPU.
 CPU-Scheduling information - Such as priority information and
pointers to scheduling queues.
 Memory-Management information - E.g. page tables or segment
tables.
 Accounting information - user and kernel CPU time consumed,
account numbers, limits, etc.
 I/O Status information - Devices allocated, open file tables, etc.
Figure 3.3 - Process control block ( PCB )

Figure 3.4 - Diagram showing CPU switch from process to process


2.1.4 Threads

 Modern systems allow a single process to have multiple threads of


execution, which execute concurrently. Threads are covered extensively
in the next chapter.

2.2 Process Scheduling

 The two main objectives of the process scheduling system are to keep the CPU
busy at all times and to deliver "acceptable" response times for all programs,
particularly for interactive ones.
 The process scheduler must meet these objectives by implementing suitable
policies for swapping processes in and out of the CPU.
 ( Note that these objectives can be conflicting. In particular, every time the
system steps in to swap processes it takes up time on the CPU to do so, which
is thereby "lost" from doing any useful productive work. )

2.2.1 Scheduling Queues

 All processes are stored in the job queue.


 Processes in the Ready state are placed in the ready queue.
 Processes waiting for a device to become available or to deliver data are
placed in device queues. There is generally a separate device queue for
each device.
 Other queues may also be created and used as needed.
Figure 3.5 - The ready queue and various I/O device queues

2.2.2 Schedulers

 A long-term scheduler is typical of a batch system or a very heavily


loaded system. It runs infrequently, ( such as when one process ends
selecting one more to be loaded in from disk in its place ), and can
afford to take the time to implement intelligent and advanced
scheduling algorithms.
 The short-term scheduler, or CPU Scheduler, runs very frequently, on
the order of 100 milliseconds, and must very quickly swap one process
out of the CPU and swap in another one.
 Some systems also employ a medium-term scheduler. When system
loads get high, this scheduler will swap one or more processes out of the
ready queue system for a few seconds, in order to allow smaller faster
jobs to finish up quickly and clear the system. See the differences in
Figures 3.7 and 3.8 below.
 An efficient scheduling system will select a good process
mix of CPU-bound processes and I/O bound processes.
Figure 3.6 - Queueing-diagram representation of process scheduling

Figure 3.7 - Addition of a medium-term scheduling to the queueing


diagram

2.2.3 Context Switch

 Whenever an interrupt arrives, the CPU must do a state-save of the


currently running process, then switch into kernel mode to handle the
interrupt, and then do a state-restore of the interrupted process.
 Similarly, a context switch occurs when the time slice for one process
has expired and a new process is to be loaded from the ready queue.
This will be instigated by a timer interrupt, which will then cause the
current process's state to be saved and the new process's state to be
restored.
 Saving and restoring states involves saving and restoring all of the
registers and program counter(s), as well as the process control blocks
described above.
 Context switching happens VERY VERY frequently, and the overhead
of doing the switching is just lost CPU time, so context switches ( state
saves & restores ) need to be as fast as possible. Some hardware has
special provisions for speeding this up, such as a single machine
instruction for saving or restoring all registers at once.
 Some Sun hardware actually has multiple sets of registers, so the context
switching can be speeded up by merely switching which set of registers
are currently in use. Obviously there is a limit as to how many processes
can be switched between in this manner, making it attractive to
implement the medium-term scheduler to swap some processes out as
shown in Figure 3.8 above.
2.3 Operations on Processes

2.3.1 Process Creation

 Processes may create other processes through appropriate system calls,


such as fork or spawn. The process which does the creating is termed
the parent of the other process, which is termed its child.
 Each process is given an integer identifier, termed its process identifier,
or PID. The parent PID ( PPID ) is also stored for each process.
 On typical UNIX systems the process scheduler is termed sched, and is
given PID 0. The first thing it does at system startup time is to
launch init, which gives that process PID 1. Init then launches all
system daemons and user logins, and becomes the ultimate parent of all
other processes. Figure 3.9 shows a typical process tree for a Linux
system, and other systems will have similar though not identical trees:

Figure 3.8 - A tree of processes on a typical Linux system

Depending on system implementation, a child process may receive some


amount of shared resources with its parent. Child processes may or may not be
limited to a subset of the resources originally allocated to the parent,
preventing runaway children from consuming all of a certain system resource.

There are two options for the parent process after creating the child:

1. Wait for the child process to terminate before proceeding. The parent makes
a wait( ) system call, for either a specific child or for any child, which causes
the parent process to block until the wait( ) returns. UNIX shells normally wait
for their children to complete before issuing a new prompt.
2. Run concurrently with the child, continuing to process without waiting. This
is the operation seen when a UNIX shell runs a process as a background task. It
is also possible for the parent to run for a while, and then wait for the child
later, which might occur in a sort of a parallel processing operation. ( E.g. the
parent may fork off a number of children without waiting for any of them, then
do a little work of its own, and then wait for the children. )

3.3.2 Process Termination


 Processes may request their own termination by making
the exit( ) system call, typically returning an int. This int is passed along
to the parent if it is doing a wait( ), and is typically zero on successful
completion and some non-zero code in the event of problems.

o child code:

int exitCode;
exit( exitCode ); // return
exitCode; has the same effect when executed from main( )

parent code:
pid_t pid;
int status
pid = wait( &status ); // pid indicates which child exited.
exitCode in low-order bits of status // macros can test the high-order bits of
status for why it stopped

Processes may also be terminated by the system for a variety of reasons,


including:

 The inability of the system to deliver necessary system resources.


 In response to a KILL command, or other un handled process
interrupt.
 A parent may kill its children if the task assigned to them is no
longer needed.
 If the parent exits, the system may or may not allow the child to
continue without a parent.

When a process terminates, all of its system resources are freed up,
open files flushed and closed, etc. The process termination status and
execution times are returned to the parent if the parent is waiting for the
child to terminate, or eventually returned to init if the process becomes an
orphan. ( Processes which are trying to terminate but which cannot because
their parent is not waiting for them are termed zombies. These are
eventually inherited by init as orphans and killed off. Note that modern
UNIX shells do not produce as many orphans and zombies as older
systems used to. )
2.4 Interprocess Communication

 Independent Processes operating concurrently on a systems are those that can


neither affect other processes or be affected by other processes.

Cooperating Processes are those that can affect or be affected by other


processes. There are several reasons why cooperating processes are allowed:

o Information Sharing - There may be several processes which need access to the
same file for example. ( e.g. pipelines. )
o Computation speedup - Often a solution to a problem can be solved faster if the
problem can be broken down into sub-tasks to be solved simultaneously
( particularly when multiple processors are involved. )
o Modularity - The most efficient architecture may be to break a system down
into cooperating modules. ( E.g. databases with a client-server architecture. )
o Convenience - Even a single user may be multi-tasking, such as editing,
compiling, printing, and running the same code in different windows.
 Cooperating processes require some type of inter-process
communication, which is most commonly one of two types: Shared Memory
systems or Message Passing systems.

Communications models: (a) Message passing. (b) Shared memory.

 Shared Memory is faster once it is set up, because no system calls are required
and access occurs at normal memory speeds. However it is more complicated
to set up, and doesn't work as well across multiple computers. Shared memory
is generally preferable when large amounts of information must be shared
quickly on the same computer.
 Message Passing requires system calls for every message transfer, and is
therefore slower, but it is simpler to set up and works well across multiple
computers. Message passing is generally preferable when the amount and/or
frequency of data transfers is small, or when multiple computers are involved.

3.4.1 Shared-Memory Systems

 In general the memory to be shared in a shared-memory system is


initially within the address space of a particular process, which needs to
make system calls in order to make that memory publicly available to
one or more other processes.
 Other processes which wish to use the shared memory must then make
their own system calls to attach the shared memory area onto their
address space.
 Generally a few messages must be passed back and forth between the
cooperating processes first in order to set up and coordinate the shared
memory access.
Inter Process Communication (IPC) is a mechanism that involves communication of one process
with another process. This usually occurs only in one system.
Communication can be of two types −
 Between related processes initiating from only one process, such as parent and child
processes.
 Between unrelated processes, or two or more different processes.
Following are some important terms that we need to know before proceeding further on this
topic.
Pipes − Communication between two related processes. The mechanism is half duplex meaning
the first process communicates with the second process. To achieve a full duplex i.e., for the
second process to communicate with the first process another pipe is required.
FIFO − Communication between two unrelated processes. FIFO is a full duplex, meaning the
first process can communicate with the second process and vice versa at the same time.
Message Queues − Communication between two or more processes with full duplex capacity.
The processes will communicate with each other by posting a message and retrieving it out of
the queue. Once retrieved, the message is no longer available in the queue.
Shared Memory − Communication between two or more processes is achieved through a
shared piece of memory among all processes. The shared memory needs to be protected from
each other by synchronizing access to all the processes.
Semaphores − Semaphores are meant for synchronizing access to multiple processes. When
one process wants to access the memory (for reading or writing), it needs to be locked (or
protected) and released when the access is removed. This needs to be repeated by all the
processes to secure data.
Signals − Signal is a mechanism to communication between multiple processes by way of
signaling. This means a source process will send a signal (recognized by number) and the
destination process will handle it accordingly.
Note − Almost all the programs in this tutorial are based on system calls under Linux Operating
System (executed in Ubuntu).

Producer-Consumer Example Using Shared Memory

 This is a classic example, in which one process is producing data and


another process is consuming the data. ( In this example in the order in
which it is produced, although that could vary. )
 The data is passed via an intermediary buffer, which may be either
unbounded or bounded. With a bounded buffer the producer may have
to wait until there is space available in the buffer, but with an
unbounded buffer the producer will never need to wait. The consumer
may need to wait in either case until there is data available.
 This example uses shared memory and a circular queue. Note in the
code below that only the producer changes "in", and only the consumer
changes "out", and that they can never be accessing the same array
location at the same time.
 First the following data is set up in the shared
memory area:

#define BUFFER_SIZE 10

typedef struct {
...
} item;

item buffer[ BUFFER_SIZE ];


int in = 0;
int out = 0;

/*Then the producer process. Note that the buffer is full


when "in" is one less than "out" in a circular sense:*/

item nextProduced;

while( true ) {

/* Produce an item and store it in nextProduced */


nextProduced = makeNewItem( . . . );

/* Wait for space to become available */


while( ( ( in + 1 ) % BUFFER_SIZE ) == out )
; /* Do nothing */

/* And then store the item and repeat the loop. */


buffer[ in ] = nextProduced;
in = ( in + 1 ) % BUFFER_SIZE;

Then the consumer process. Note that the buffer is empty when "in"
is equal to "out":

item nextConsumed;

while( true ) {

/* Wait for an item to become available */


while( in == out )
; /* Do nothing */

/* Get the next available item */


nextConsumed = buffer[ out ];
out = ( out + 1 ) % BUFFER_SIZE;

/* Consume the item in nextConsumed


( Do something with it ) */

3.4.2 Message-Passing Systems

 Message passing systems must support at a minimum system calls for


"send message" and "receive message".
 A communication link must be established between the cooperating
processes before messages can be sent.
 There are three key issues to be resolved in message passing systems as
further explored in the next three subsections:

o Direct or indirect communication ( naming )


o Synchronous or asynchronous communication
o Automatic or explicit buffering.

3.4.2.1 Naming

 With direct communication the sender must know the name of the
receiver to which it wishes to send a message.

There is a one-to-one link between every sender-receiver pair.

For symmetric communication, the receiver must also know the specific name of
the sender from which it wishes to receive messages.
For asymmetric communications, this is not necessary.

Indirect communication uses shared mailboxes, or ports.

Multiple processes can share the same mailbox or boxes.

Only one process can read any given message in a mailbox. Initially the process
that creates the mailbox is the owner, and is the only one allowed to read mail in
the mailbox, although this privilege may be transferred.

( Of course the process that reads the message can immediately turn around and
place an identical message back in the box for someone else to read, but that may
put it at the back end of a queue of messages. )

The OS must provide system calls to create and delete mailboxes, and to send and
receive messages to/from mailboxes.

2.4.2.2 Synchronization
Either the sending or receiving of messages ( or neither or both ) may be
either blocking or non-blocking.

2.4.2.3 Buffering

Messages are passed via queues, which may have one of three capacity
configurations:

Zero capacity - Messages cannot be stored in the queue, so senders must block
until receivers accept the messages.

Bounded capacity- There is a certain pre-determined finite capacity in the queue.


Senders must block if the queue is full, until space becomes available in the
queue, but may be either blocking or non-blocking otherwise.

Unbounded capacity - The queue has a theoretical infinite capacity, so senders


are never forced to block.

Multi-Threading:

What is Thread?

A thread is a flow of execution through the process code, with its own program counter that
keeps track of which instruction to execute next, system registers which hold its current
working variables, and a stack which contains the execution history.

A thread shares with its peer threads few information like code segment, data segment and
open files. When one thread alters a code segment memory item, all other threads see that.

A thread is also called a lightweight process. Threads provide a way to improve application
performance through parallelism. Threads represent a software approach to improving
performance of operating system by reducing the overhead thread is equivalent to a classical
process.
Each thread belongs to exactly one process and no thread can exist outside a process. Each
thread represents a separate flow of control. Threads have been successfully used in
implementing network servers and web server. They also provide a suitable foundation for
parallel execution of applications on shared memory multiprocessors. The following figure
shows the working of a single-threaded and a multithreaded process.

Difference between Process and Thread:

S.N Process Thread


.

1 Process is heavy weight or resource Thread is light weight, taking lesser


intensive. resources than a process.

2 Process switching needs interaction Thread switching does not need to


with operating system. interact with operating system.

3 In multiple processing environments, All threads can share same set of open
each process executes the same code files, child processes.
but has its own memory and file
resources.

4 If one process is blocked, then no other While one thread is blocked and
process can execute until the first waiting, a second thread in the same
process is unblocked. task can run.
5 Multiple processes without using Multiple threaded processes use fewer
threads use more resources. resources.

6 In multiple One thread can read, write or change


processes each another thread's data.
process operates
independently of
the others.

Advantages of Thread

 Threads minimize the context switching time.


 Use of threads provides concurrency within a process.
 Efficient communication.
 It is more economical to create and context switch threads.
 Threads allow utilization of multiprocessor architectures to a greater scale and
efficiency.

Types of Thread:

Threads are implemented in following two ways −

 User Level Threads − User managed threads.


 Kernel Level Threads − Operating System managed threads acting on kernel, an
operating system core.

Multithreading Models

Some operating system provide a combined user level thread and Kernel level thread
facility. Solaris is a good example of this combined approach. In a combined system,
multiple threads within the same application can run in parallel on multiple processors
and a blocking system call need not block the entire process. Multithreading models are
three types.

 Many to many relationship.


 Many to one relationship.
 One to one relationship.

Many to Many Model

The many-to-many model multiplexes any number of user threads onto an equal or
smaller number of kernel threads.
The following diagram shows the many-to-many threading model where 6 user level
threads are multiplexing with 6 kernel level threads. In this model, developers can create
as many user threads as necessary and the corresponding Kernel threads can run in
parallel on a multiprocessor machine. This model provides the best accuracy on
concurrency and when a thread performs a blocking system call, the kernel can schedule
another thread for execution.

Many to One Model

Many-to-one model maps many user level threads to one Kernel-level thread. Thread
management is done in user space by the thread library. When thread makes a blocking
system call, the entire process will be blocked. Only one thread can access the Kernel at
a time, so multiple threads are unable to run in parallel on multiprocessors.
If the user-level thread libraries are implemented in the operating system in such a way
that the system does not support them, then the Kernel threads use the many-to-one
relationship modes.
One to One Model

There is one-to-one relationship of user-level thread to the kernel-level thread. This


model provides more concurrency than the many-to-one model. It also allows another
thread to run when a thread makes a blocking system call. It supports multiple threads to
execute in parallel on microprocessors.
Disadvantage of this model is that creating user thread requires the corresponding
Kernel thread. OS/2, windows NT and windows 2000 use one to one relationship
model.
Difference between User-Level & Kernel-Level Thread

S.N. User-Level Threads Kernel-Level Thread

1 User-level threads are faster to create and Kernel-level threads are slower to
manage. create and manage.

2 Implementation is by a thread library at the Operating system supports creation


user level. of Kernel threads.

3 User-level thread is generic and can run on Kernel-level thread is specific to


any operating system. the operating system.

4 Multi-threaded applications cannot take Kernel routines themselves can be


advantage of multiprocessing. multithreaded.

CPU Scheduling

Almost all programs have some alternating cycle of CPU number crunching
and waiting for I/O of some kind. ( Even a simple fetch from memory takes
a long time relative to CPU speeds. )
In a simple system running a single process, the time spent waiting for I/O is
wasted, and those CPU cycles are lost forever.

A 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.

The challenge is to make the overall system as "efficient" and "fair" as


possible, subject to varying and often dynamic conditions, and where
"efficient" and "fair" are somewhat subjective terms, often subject to
shifting priority policies.

CPU-I/O Burst Cycle

Almost all processes alternate between two states in a continuing cycle, as


shown in Figure below :

 A CPU burst of performing calculations, and


 An I/O burst, waiting for data transfer in or out of the system.

CPU bursts vary from process to process, and from program to program, but an extensive
study shows frequency patterns similar to that shown in Figure below
Fig:Histogram of CPU Burst Duration

CPU Scheduler

Whenever the CPU becomes idle, it is the job of the CPU Scheduler ( a.k.a. the short-term
scheduler ) to select another process from the ready queue to run next.

The storage structure for the ready queue and the algorithm used to select the next process are not
necessarily a FIFO queue. There are several alternatives to choose from, as well as numerous
adjustable parameters for each algorithm, which is the basic subject of this entire chapter.

5.1.3. Preemptive Scheduling

CPU scheduling decisions take place under one of four conditions:

When a process switches from the running state to the waiting state, such as for an I/O request or
invocation of the wait( ) system call.

When a process switches from the running state to the ready state, for example in response to an
interrupt.

When a process switches from the waiting state to the ready state, say at completion of I/O or a
return from wait( ).

When a process terminates.

For conditions 1 and 4 there is no choice - A new process must be selected.


For conditions 2 and 3 there is a choice - To either continue running the current process, or select
a different one.

If scheduling takes place only under conditions 1 and 4, the system is said to be non-preemptive,
or cooperative. Under these conditions, once a process starts running it keeps running, until it
either voluntarily blocks or until it finishes. Otherwise the system is said to be preemptive.

Windows used non-preemptive scheduling up to Windows 3.x, and started using pre-emptive
scheduling with Win95. Macs used non-preemptive prior to OSX, and pre-emptive since then.
Note that pre-emptive scheduling is only possible on hardware that supports a timer interrupt.

Note that pre-emptive scheduling can cause problems when two processes share data, because
one process may get interrupted in the middle of updating shared data structures. Chapter 6 will
examine this issue in greater detail.

Preemption can also be a problem if the kernel is busy implementing a system call ( e.g. updating
critical kernel data structures ) when the preemption occurs. Most modern UNIXes deal with this
problem by making the process wait until the system call has either completed or blocked before
allowing the preemption Unfortunately this solution is problematic for real-time systems, as
real-time response can no longer be guaranteed.

Some critical sections of code protect themselves from concurrency problems by disabling
interrupts before entering the critical section and re-enabling interrupts on exiting the section.
Needless to say, this should only be done in rare situations, and only on very short pieces of code
that will finish quickly, ( usually just a few machine instructions. )

Dispatcher

The dispatcher is the module that gives control of the CPU to the process selected by the
scheduler. This function involves:

 Switching context.
 Switching to user mode.
 Jumping to the proper location in the newly loaded program.

The dispatcher needs to be as fast as possible, as it is run on every context switch. The time
consumed by the dispatcher is known as dispatch latency.

Scheduling Criteria

There are several different criteria to consider when trying to select the "best" scheduling
algorithm for a particular situation and environment, including:

 CPU utilization - Ideally the CPU would be busy 100% of the time, so as to waste 0 CPU
cycles. On a real system CPU usage should range from 40% ( lightly loaded ) to 90%
( heavily loaded. )
 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. ( Wall clock time. )
 Waiting time - How much time processes spend in the ready queue waiting their turn to get
on the CPU. ( Load average - The average number of processes sitting in the ready queue
waiting their turn to get into the CPU. Reported in 1-minute, 5-minute, and 15-minute
averages by "uptime" and "who". )
 Response time - The time taken in an interactive program from the issuance of a command
to the commence of a response to that command.

In general one wants to optimize the average value of a criteria ( Maximize CPU utilization and
throughput, and minimize all the others. ) However some times one wants to do something
different, such as to minimize the maximum response time.

Sometimes it is most desirable to minimize the variance of a criteria than the actual value. I.e.
users are more accepting of a consistent predictable system than an inconsistent one, even if it is
a little bit slower.

Scheduling Algorithms

The following subsections will explain several common scheduling strategies, looking at only a
single CPU burst each for a small number of processes. Obviously real systems have to deal with
a lot more simultaneous processes executing their CPU-I/O burst cycles.

1. First-Come First-Serve Scheduling, FCFS

FCFS is very simple - Just a FIFO queue, like customers waiting in line at the bank or the post
office or at a copying machine.

Unfortunately, however, FCFS can yield some very long average wait times, particularly if the
first process to get there takes a long time. For example, consider the following three processes:

Process Burst Time

P1 24

P2 3

P3 3

 In the first Gantt chart below, process P1 arrives first. The average waiting time for the three
processes is ( 0 + 24 + 27 ) / 3 = 17.0 ms.
 In the second Gantt chart below, the same three processes have an average wait time of ( 0 +
3 + 6 ) / 3 = 3.0 ms. The total run time for the three bursts is the same, but in the second case
two of the three finish much quicker, and the other process is only delayed by a short
amount.
 FCFS can also block the system in a busy dynamic system in another way, known as
the convoy effect. When one CPU intensive process blocks the CPU, a number of I/O
intensive processes can get backed up behind it, leaving the I/O devices idle. When the CPU
hog finally relinquishes the CPU, then the I/O processes pass through the CPU quickly,
leaving the CPU idle while everyone queues up for I/O, and then the cycle repeats itself
when the CPU intensive process gets back to the ready queue.

2. Shortest-Job-First Scheduling, SJF

The idea behind the SJF algorithm is to pick the quickest fastest little job that needs to be done,
get it out of the way first, and then pick the next smallest fastest job to do next.

( Technically this algorithm picks a process based on the next shortest CPU burst, not the overall
process time. )

For example, the Gantt chart below is based upon the following CPU burst times, ( and the
assumption that all jobs arrive at the same time. )

Process Burst Time


P1 6
P2 8
P3 7
P4 3

In the case above the average wait time is ( 0 + 3 + 9 + 16 ) / 4 = 7.0 ms, ( as opposed to 10.25
ms for FCFS for the same processes. )

SJF can be proven to be the fastest scheduling algorithm, but it suffers from one important
problem: How do you know how long the next CPU burst is going to be?

For long-term batch jobs this can be done based upon the limits that users set for their jobs when
they submit them, which encourages them to set low limits, but risks their having to re-submit
the job if they set the limit too low. However that does not work for short-term CPU scheduling
on an interactive system.

Another option would be to statistically measure the run time characteristics of jobs, particularly
if the same tasks are run repeatedly and predictably. But once again that really isn't a viable
option for short term CPU scheduling in the real world.

A more practical approach is to predict the length of the next burst, based on some historical
measurement of recent burst times for this process. One simple, fast, and relatively accurate
method is the exponential average, which can be defined as follows. ( The book uses tau and t for
their variables, but those are hard to distinguish from one another and don't work well in
HTML. )

estimate[ i + 1 ] = alpha * burst[ i ] + ( 1.0 - alpha ) * estimate[ i ]

In this scheme the previous estimate contains the history of all previous times, and alpha serves
as a weighting factor for the relative importance of recent data versus past history. If alpha is 1.0,
then past history is ignored, and we assume the next burst will be the same length as the last burst.
If alpha is 0.0, then all measured burst times are ignored, and we just assume a constant burst
time. Most commonly alpha is set at 0.5, as illustrated in Figure 5.3:

SJF can be either preemptive or non-preemptive. Preemption occurs when a new process arrives
in the ready queue that has a predicted burst time shorter than the time remaining in the process
whose burst is currently on the CPU. Preemptive SJF is sometimes referred to as shortest
remaining time first scheduling.

For example, the following Gantt chart is based upon the following data:

Process Arrival Time Burst Time


P1 0 8
P2 1 4
P3 2 9
p4 3 5

The average wait time in this case is ( ( 5 - 3 ) + ( 10 - 1 ) + ( 17 - 2 ) ) / 4 = 26 / 4 = 6.5 ms. ( As


opposed to 7.75 ms for non-preemptive SJF or 8.75 for FCFS. )

3. Priority Scheduling

Priority scheduling is a more general case of SJF, in which each job is assigned a priority and the
job with the highest priority gets scheduled first. ( SJF uses the inverse of the next expected burst
time as its priority - The smaller the expected burst, the higher the priority. )

Note that in practice, priorities are implemented using integers within a fixed range, but there is
no agreed-upon convention as to whether "high" priorities use large numbers or small numbers.
This book uses low number for high priorities, with 0 being the highest possible priority.

For example, the following Gantt chart is based upon these process burst times and priorities, and
yields an average waiting time of 8.2 ms:

Process Burst Time Priority


P1 10 3
P2 1 1
P3 2 4
P4 1 5
P5 5 2

Priorities can be assigned either internally or externally. Internal priorities are assigned by the OS
using criteria such as average burst time, ratio of CPU to I/O activity, system resource use, and
other factors available to the kernel. External priorities are assigned by users, based on the
importance of the job, fees paid, politics, etc.

Priority scheduling can be either preemptive or non-preemptive.


Priority scheduling can suffer from a major problem known as indefinite blocking, or starvation,
in which a low-priority task can wait forever because there are always some other jobs around
that have higher priority.

If this problem is allowed to occur, then processes will either run eventually when the system
load lightens ( at say 2:00 a.m. ), or will eventually get lost when the system is shut down or
crashes. ( There are rumors of jobs that have been stuck for years. )

One common solution to this problem is aging, in which priorities of jobs increase the longer
they wait. Under this scheme a low-priority job will eventually get its priority raised high enough
that it gets run.

4. Shortest Remaining Time

Shortest remaining time (SRT) is the preemptive version of the SJN algorithm.

The processor is allocated to the job closest to completion but it can be preempted by a newer
ready job with shorter time to completion.

Impossible to implement in interactive systems where required CPU time is not known.

It is often used in batch environments where short jobs need to give preference.

5. Round Robin Scheduling

Round robin scheduling is similar to FCFS scheduling, except that CPU bursts are assigned with
limits called time quantum.

When a process is given the CPU, a timer is set for whatever value has been set for a time
quantum.

If the process finishes its burst before the time quantum timer expires, then it is swapped out of
the CPU just like the normal FCFS algorithm.

If the timer goes off first, then the process is swapped out of the CPU and moved to the back end
of the ready queue.

The ready queue is maintained as a circular queue, so when all processes have had a turn, then
the scheduler gives the first process another turn, and so on.

RR scheduling can give the effect of all processors sharing the CPU equally, although the
average wait time can be longer than with other scheduling algorithms. In the following example
the average wait time is 5.66 ms.

Process Burst Time


P1 24
P2 3
P3 3
The performance of RR is sensitive to the time quantum selected. If the quantum is large enough,
then RR reduces to the FCFS algorithm; If it is very small, then each process gets 1/nth of the
processor time and share the CPU equally.

BUT, a real system invokes overhead for every context switch, and the smaller the time quantum
the more context switches there are. ( See Figure 5.4 below. ) Most modern systems use time
quantum between 10 and 100 milliseconds, and context switch times on the order of 10
microseconds, so the overhead is small relative to the time quantum.

Turn around time also varies with quantum time, in a non-apparent manner. Consider, for
example the processes shown in Figure 5.5:
In general, turnaround time is minimized if most processes finish their next cpu burst within one
time quantum. For example, with three processes of 10 ms bursts each, the average turnaround
time for 1 ms quantum is 29, and for 10 ms quantum it reduces to 20. However, if it is made too
large, then RR just degenerates to FCFS. A rule of thumb is that 80% of CPU bursts should be
smaller than the time quantum.

6. Multilevel Queue Scheduling

When processes can be readily categorized, then multiple separate queues can be established,
each implementing whatever scheduling algorithm is most appropriate for that type of job, and/or
with different parametric adjustments.

Scheduling must also be done between queues, that is scheduling one queue to get time relative
to other queues. Two common options are strict priority ( no job in a lower priority queue runs
until all higher priority queues are empty ) and round-robin ( each queue gets a time slice in turn,
possibly of different sizes. )

Note that under this algorithm jobs cannot switch from queue to queue - Once they are assigned a
queue, that is their queue until they finish.
Algorithm Evaluation

The first step in determining which algorithm ( and what parameter settings within that
algorithm ) is optimal for a particular operating environment is to determine what criteria
are to be used, what goals are to be targeted, and what constraints if any must be applied.
For example, one might want to "maximize CPU utilization, subject to a maximum
response time of 1 second".

Once criteria have been established, then different algorithms can be analyzed and a
"best choice" determined. The following sections outline some different methods for
determining the "best choice".

1. Deterministic Modeling
2. Queuing models
3. Simulation
4. Implementation

1. Deterministic Modelling:

If a specific workload is known, then the exact values for major criteria can be fairly
easily calculated, and the "best" determined. For example, consider the following
workload ( with all processes arriving at time 0 ), and the resulting schedules determined
by three different algorithms:

Process Burst Time


P1 10
P2 29
P3 3
P4 7
P5 12

The average waiting times for FCFS, SJF, and RR are 28ms, 13ms, and 23ms
respectively.

Deterministic modeling is fast and easy, but it requires specific known input, and the
results only apply for that particular set of input. However by examining multiple similar
cases, certain trends can be observed. ( Like the fact that for processes arriving at the
same time, SJF will always yield the shortest average wait time. )

2. Queuing Models

Specific process data is often not available, particularly for future times. However a
study of historical performance can often produce statistical descriptions of certain
important parameters, such as the rate at which new processes arrive, the ratio of CPU
bursts to I/O times, the distribution of CPU burst times and I/O burst times, etc.

Armed with those probability distributions and some mathematical formulas, it is


possible to calculate certain performance characteristics of individual waiting queues.
For example, Little's Formula says that for an average queue length of N, with an
average waiting time in the queue of W, and an average arrival of new jobs in the queue
of Lambda, then these three terms can be related by:

N = Lambda * W

Queuing models treat the computer as a network of interconnected queues, each of which
is described by its probability distribution statistics and formulas such as Little's formula.
Unfortunately real systems and modern scheduling algorithms are so complex as to make
the mathematics intractable in many cases with real systems.

3. Simulations

Rather than using queuing models we simulate a computer. A Variable, representing a


clock is incremented. At each increment the state of the simulation is updated.

Statistics are gathered at each clock tick so that the system performance can be analysed.

The data to drive the simulation can be generated in the same way as the queuing model,
although this leads to similar problems.

Alternatively, we can use trace data. This is data collected from real processes on real
machines and is fed into the simulation. This can often provide good results and good
comparisons over a range of scheduling algorithms.

However, simulations can take a long time to run, can take a long time to implement and
the trace data may be difficult to collect and require large amounts of storage.
4. Implementation

The best way to compare algorithms is to implement them on real machines. This will
give the best results but does have a number of disadvantages.

· It is expensive as the algorithm has to be written and then implemented on real


hardware.
· If typical workloads are to be monitored, the scheduling algorithm must be used in a
live situation. Users may not be happy with an environment that is constantly changing.
· If we find a scheduling algorithm that performs well there is no guarantee that this state
will continue if the workload or environment changes.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy