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

CML23304-OPERATING SYSTEM Module 2 Notes

Notes

Uploaded by

kenishaken07
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views

CML23304-OPERATING SYSTEM Module 2 Notes

Notes

Uploaded by

kenishaken07
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Operating Systems NOTES

(CML23304)

Compiled by
Dr. Chandramma R
Basic Concept
In a system with a single CPU core, only one process can run at a time. Others must wait until the CPU’s core
is free and can be rescheduled. The objective of multiprogramming is to have some process running at all
times, to maximize CPU utilization. The idea is relatively simple.A process is executed until it must wait,
typically for the completion of some I/O request. In a simple computer
system, the CPU then just sits idle. All this waiting time is wasted; no useful work is accomplished .With
multiprogramming,we try to use this time productively.

Several processes are kept in memory at one time. When one process has to wait, the operating system takes
the CPU away from that process and gives the CPU to another process. This pattern continues. Every time one
process has to wait, another process can take over use of the CPU. On a multicore system, this concept of
keeping the CPU busy is extended to all processing cores on the system .Scheduling of this kind is a
fundamental operating-system function. Almost all computer resources are scheduled before use. The CPU is,
of course, one of the primary computer resources. Thus, its scheduling is central to operating-system design.

CPU–I/O Burst Cycle

The success of CPU scheduling depends on an observed property of processes: process execution
consists of a cycle of CPU execution and I/O wait. Processes alternate between these two states.
Process execution begins with a CPU burst.
That is followed by an I/O burst, which is followed by another CPU burst, then another I/O
burst, and so on. Eventually, the final CPU burst ends with a system request to terminate
execution
The durations of CPU bursts have been measured extensively. Although they vary greatly from
process to process and from computer to computer, they tend to have a frequency curve similar
to that shown in Figure 5.2. The curve is generally characterized as exponential or hyper
exponential, with a large number of short CPU bursts and a small number of long CPU bursts.
An I/O-bound program typically has many short CPU bursts. A CPU-bound program might have
a few long CPU bursts. This distribution can be important when implementing a CPU-scheduling
algorithm.

CPU-scheduling decisions may take place under the following four circumstances:

1. When a process switches from the running state to the waiting state (for example, as the result
of an I/O request or an invocation of wait() for the termination of a child process).
2. When a process switches from the running state to the ready state (for example, when an
interrupt occurs)
3. When a process switches from the waiting state to the ready state (for example, at completion of
I/O)
4. When a process terminates

For situations 1 and 4, there is no choice in terms of scheduling. Anew process (if one exists in the
ready queue) must be selected for execution. There is a choice, however, for situations 2 and 3.
When scheduling takes place only under circumstances 1 and 4,
we say that the scheduling scheme is non preemptive or cooperative. Otherwise, it is
preemptive.
Under nonpreemptive scheduling, once the CPU has been allocated to a process, the process
keeps the CPU until it releases it either by terminating or by switching to the waiting state.
Virtually all modern operating systems includingWindows,macOS, Linux, and UNIX use preemptive
scheduling algorithms.
Dispatcher
Another component involved in the CPU-scheduling function is the dispatcher.
The dispatcher is the module that gives control of the CPU’s core to the process selected by the
CPU scheduler. This function involves the following:
• Switching context from one process to another
• Switching to user mode
• Jumping to the proper location in the user program to resume that program
The dispatcher should be as fast as possible, since it is invoked during every
context switch. The time it takes for the dispatcher to stop one process and start
another running is known as the dispatch latency and is

Scheduling Criteria
Different CPU-scheduling algorithms have different properties, and the choice of a particular
algorithm may favour one class of processes over another. In choosing which algorithm to use
in a particular situation, we must consider the properties of the various algorithms.
Many criteria have been suggested for comparing CPU-scheduling algorithms.
Which characteristics are used for comparison can make a substantial difference in which
algorithm is judged to be best.
The criteria include the following:
• CPU utilization. We want to keep the CPU as busy as possible. Conceptually,
CPU utilization can range from 0 to 100 percent. In a real system, it should range from 40 percent
(for a lightly loaded system) to 90 percent (for a heavily loaded system). (CPU utilization can be
obtained by using the top command on Linux, macOS, and UNIX systems.)
• Throughput. If the CPU is busy executing processes, then work is being
done. One measure of work is the number of processes that are completed per time unit, called
throughput. For long processes, this rate may be one process over several seconds; for short
transactions, it may be tens of
processes per second.
• Turnaround time. From the point of view of a particular process, the important criterion is
how long it takes to execute that process. The interval from the time of submission of a process
to the time of completion is the turnaround time. Turnaround time is the sum of the periods spent
waiting
in the ready queue, executing on the CPU, and doing I/O.

• Waiting time. The CPU-scheduling algorithm does not affect the amount of time during which
a process executes or does I/O. It affects only the amount of time that a process spends waiting
in the ready queue.Waiting time is the sum of the periods spent waiting in the ready queue.

• Response time. In an interactive system, turnaround time may not be the best criterion. Often,
a process can produce some output fairly early and can continue computing new results while
previous results are being output to the user. Thus, another measure is the time from the
submission of a request until the first response is produced. This measure, called response time,
is the time it takes to start responding, not the time it takes to output the response.

Optimization Criteria
• Max CPU utilization
• Max throughput
• Min turnaround time
• Min waiting time
• Min response time

First-Come, First-Served Scheduling


By far the simplest CPU-scheduling algorithm is the first-come, first-served (FCFS) scheduling algorithm.
With this scheme, the process that requests the CPU first is allocated the CPU first. The implementation
of the
FCFS policy is easily managed with a FIFO queue. When a process enters the ready queue, its PCB is
linked
onto the tail of the queue. When the CPU is free, it is allocated to the process at the head of the queue.
The
running process is then removed from the queue. The code for FCFS scheduling is simple to write and
understand. The average waiting time under the FCFS policy, however, is often quite long.
Consider the following set of processes that arrive at time 0, with the length of the CPU-burst time given
in milliseconds:
Process Burst Time
PI 24
P2 3
P3 3
If the processes arrive in the order PI, P2, P3, and are served in FCFS order, we get the result shown in
the
following Gantt chart:

The waiting time is 0 milliseconds for process PI, 24 milliseconds for process PZ, and 27 milliseconds
for process P3. Thus, the average waiting time is (0 + 24 + 27)/3 = 17 milliseconds.

If the processes arrive in the order P2, P3, Pl, however, the results will be as shown in the following
Gantt chart:

The average waiting time is now (6 + 0 + 3)/3 = 3 milliseconds. This reduction is substantial. Thus, the
average waiting time under a FCFS policy is generally not minimal, and may vary substantially if the
process CPU-burst times vary greatly.

In addition, consider the performance of FCFS scheduling in a dynamic situation. Assume we have one
CPU-bound process and many I/O-bound processes. As the processes flow around the system, the
following scenario may result. The CPU-bound process will get the CPU and hold it. During this time, all
the other processes will finish their I/O and move into the ready queue, waiting for the CPU. While the
processes wait in the ready queue, the I/O devices are idle. Eventually, the CPU-bound process finishes
its CPU burst and moves to an I/O device. All the I/O-bound processes, which have very short CPU
bursts, execute quickly and move back to the I/O queues. At this point, the CPU sits idle.

The CPU-bound process will then move back to the ready queue and be allocated the CPU. Again, all
the I/O processes end up waiting in the ready queue until the CPU-bound process is done. There is a
convoy effect, as all the other processes wait for the one big process to get off the CPU. This effect results
in lower CPU and device utilization than might be possible if the shorter processes were allowed to go
first.
The FCFS scheduling algorithm is non-preemptive. Once the CPU has been allocated to a process, that
process keeps the CPU until it releases the CPU, either by terminating or by requesting I/O. The FCFS
algorithm is particularly troublesome for time-sharing systems, where each user needs to get a share of
the CPU at regular intervals. It would be disastrous to allow one process to keep the CPU for an extended
period.

Shortest-Job-First Scheduling

A different approach to CPU scheduling is the shortest-job-first (SJF) scheduling algorithm. This algorithm
associates with each process the length of the latter's next CPU burst. When the CPU is available, it is
assigned to the process that has the smallest next CPU burst. If two processes have the same length
next CPU burst,
FCFS scheduling is used to break the tie. Note that a more appropriate term would be the shortest next
CPU burst, because the scheduling is done by examining the length of the next CPU burst of a process,
rather than its total length. We use the term SJF because most people and textbooks refer to this type of
scheduling discipline as SJF.
Multilevel Queue Scheduling
Another class of scheduling algorithms has been created for situations in which processes are easily
classified into different groups. For example, a common division is made between foreground (or
interactive)
processes and background (or batch) processes. These two types of processes have different
response-time
requirements, and so might have different scheduling needs. In addition, foreground processes may
have priority
(or externally defined) over background processes.

Let’s look at an example of a multilevel queue scheduling algorithm with


four queues, listed below in order of priority:
1. Real-time processes
2. System processes
3. Interactive processes
4. Batch processes
Each queue has absolute priority over lower-priority queues. No process in the batch queue, for
example, could run unless the queues for real-time processes,system processes, and interactive
processes were all empty. If an interactive process entered the ready queue while a batch process
was running, the batch process would be preempted

Multilevel Feedback Queue Scheduling

The multilevel feedback queue scheduling algorithm, in contrast, allows a process to move
between queues. The idea is to separate processes according to the characteristics of their CPU
bursts. If a process uses too much CPU time, it will be moved to a lower-priority queue.
This scheme leaves I/O-bound and interactive processes—which are typically characterized by short
CPU bursts—in the higher-priority queues. In addition, a process that waits too long in a lower-priority
queue may be moved to a higher-priority queue. This form of aging prevents starvation.

For example, consider a multilevel feedback queue scheduler with three queues, numbered from 0
to 2 (Figure 5.9). The scheduler first executes all processes in queue 0. Only when queue 0 is
empty will it execute processes in queue 1. Similarly, processes in queue 2 will be executed only if
queues 0 and 1 are empty. A process that arrives for queue 1 will preempt a process in queue 2. A
process in queue 1 will in turn be preempted by a process arriving for queue 0.
In general, a multilevel feedback queue scheduler is defined by the following
parameters:
• The number of queues
• The scheduling algorithm for each queue
• The method used to determine when to upgrade a process to a higher priority queue
• The method used to determine when to demote a process to a lower priority queue
• The method used to determine which queue a process will enter when that process needs
service.

Process Schronization:

Concurrent access to shared data may result in data inconsistency


Maintaining data consistency requires mechanisms to ensure the orderly execution of
cooperating processes.
Suppose that we wanted to provide a solution to the consumer-producer problem that fills
all the buffers. We can do so by having an integer count that keeps track of the number
of full buffers. Initially, count is set to 0. It is incremented by the producer after it
produces a new buffer and is decremented by the consumer after it consumes a buffer.

The code for the producer process:


The code for the Consumer process:

The critical section problem


Consider a system consisting of n processes {Po,P1, ..., Pn-1). Each process has a segment of code,
called a critical section, in which the process may be changing common variables, updating a table,
writing a file, and so on. The important feature of the system is that, when one process is executing in
its critical section, no other process is to be allowed to execute in its critical section. Thus, the execution
of critical sections by the processes is mutually exclusive in time.
The critical-section problem is to design a protocol that the processes can use to cooperate. Each
process must request permission to enter its critical section.
The section of code
implementing this request is the entry section.
The critical section may be followed by an exit section.
The remaining code is the remainder section.
do{
Entry section
Critical section
Exit section
Remainder section
} while(1);

A solution to the critical-section problem must satisfy the following three requirements:

1. Mutual Exclusion: If process Pi is executing in its critical section, then no other processes can
be executing in their critical sections.

2. Progress: If no process is executing in its critical section and some processes wish to enter their
critical sections, then only those processes that are not executing in their remainder section can
participate in the decision on which will enter its critical section next, and this selection cannot be
postponed indefinitely.

3. Bounded Waiting: There exists a bound on the number of times that other processes are allowed
to enter their critical sections after a process has made a request to enter its critical section and before
that request is granted.
 We would arrive at this incorrect state because we allowed both processes
to manipulate the variable count concurrently.
 A situation like this, where several processes access and manipulate the same data
concurrently and the outcome of the execution depends on the particular order in which
the access takes place, is called a race condition.
 To guard against the race condition above, we need to ensure that only one process at a
time can be manipulating the variable count.

Peterson’s Solution:
Peterson’s solution is a software based solution to the critical section problem.
Consider two processes P0 and P1. For convenience, when presenting Pi, we use Pi to denote the
other process; that is, j == 1 - i.
The processes share two variables:
boolean flag [2] ;
int turn;
Initially flag [0] = flag [1] = false, and the value of turn is immaterial (but is either 0 or 1).

The structure of process Pi is shown below.


Mutex Locks

The simplest of these tools is the mutex lock. (In fact, the termmutex is short for mutual exclusion.)
We use the mutex lock to protect critical sections and thus prevent race conditions.
That is, a process must acquire the lock before entering a critical section; it releases the lock when
it exits the critical section. The acquire()function acquires the lock, and the release() function
releases the lock.

A mutex lock has a boolean variable available whose value indicates if the lock is available or not.
If the lock is available, a call to acquire() succeeds,and the lock is then considered unavailable.
Aprocess that attempts to acquire an unavailable lock is blocked until the lock is released.

The main disadvantage of the implementation given here is that it requires busy waiting. While a
process is in its critical section, any other process that tries to enter its critical section must loop
continuously in the call to acquire(). This continual looping is clearly a problem in a real
multiprogramming system, where a single CPU core is shared among many processes. Busy waiting
also wastes CPU cycles that some other process might be able to use productively.
The type of mutex lock we have been describing is also called a spinlock because the process
“spins” while waiting for the lock to become available.
n Counting semaphore – integer value can range
over an unrestricted domain
n Binary semaphore – integer value can range only
between 0
and 1; can be simpler to implement
l Also known as mutex locks
n Can implement a counting semaphore S as a
binary semaphore
n Provides mutual exclusion
Semaphore mutex; // initialized to 1
do {
wait (mutex);
// Critical Section
signal (mutex);
// remainder section
} while (TRUE);
Note that, if a writer is in the critical section and n readers are waiting, then one reader is queued on
wrt, and n - 1 readers are queued on mutex. Also observe that, when a writer executes signal (wrt), we
may resume the execution of either the waiting readers or a single waiting writer.

The Dining-Philosophers Problem


Consider five philosophers who spend their lives thinking and eating. The philosophers share a
circular table surrounded by five chairs, each belonging to one philosopher. In the centre of the
table is a bowl of rice, and the table is laid with five single chopsticks Figure below . When a
philosopher thinks, she does not interact with her colleagues. From time to time, a philosopher
gets hungry and tries to pick up the two chopsticks that are closest to her A philosopher may
pick up only one chopstick at a time. Obviously, she cannot pick up a chopstick that is already
in the hand of a neighbour. When a hungry philosopher has both her chopsticks at the same
time, she eats without releasing the chopsticks. When she is finished eating, she puts down
both chopsticks and starts thinking again.
The dining-philosophers problem is considered a classic synchronization problem neither
because of its practical importance nor because computer scientists dislike philosophers but
because it is an example of a large class of concurrency-control problems. It is a simple
representation of the need to allocate several resources among several processes in a deadlock-
free and starvation-free manner.

Semaphore Solution
Monitor Solution

monitor DP void test (int i) {


{ if ( (state[(i + 4) % 5] != EATING)
enum { THINKING; HUNGRY, EATING) state
&&
[5] ; (state[i] == HUNGRY) &&
condition self [5]; (state[(i + 1) % 5] != EATING) ) {
void pickup (int i) { state[i] = EATING ;
state[i] = HUNGRY; self[i].signal () ;
test(i);
}
if (state[i] != EATING) self [i].wait;
}
}
initialization_code() {
void putdown (int i) {
for (int i = 0; i < 5; i++)
state[i] = THINKING;
state[i] = THINKING;
// test left and right neighbors
test((i + 4) % 5);
}
test((i + 1) % 5); }
}

You might also like