OS Process
OS Process
• PCB simply serves as the repository for any information that may vary from
process to process. It contains many pieces of information associated with a
specific process, including these:
• Process state: The state may be new, ready, running, waiting, halted, and so
on.
• Program counter: The counter indicates the address of the next instruction
to be executed for this process.
• CPU registers: The registers vary in number and type, depending on the
computer architecture. They include accumulators, index registers, stack
pointers, and general-purpose registers, plus any condition-code information.
Along with the program counter, this state information must be saved when
an interrupt occurs, to allow the process to be continued correctly afterward.
• CPU-scheduling information: This information includes a
process priority, pointers to scheduling queues, and any
other scheduling parameters.
• Waiting (Blocked): The process is waiting for some event to occur (such as an I/O
completion or reception of a signal).
• A process continues this cycle until it terminates, at which time it is removed from all queues
and has its PCB and resources deallocated.
Schedulers
• Schedulers: A process migrates among the various scheduling queues throughout its lifetime. The operating
system must select, for scheduling purposes, processes from these queues in some fashion. The selection process
is carried out by the appropriate scheduler.
• Types of Schedulers
• Long Term Schedulers (LTS)/Spooler: In multiprogramming os, more processes are submitted than can be
executed immediately. These processes are spooled to a mass-storage device (typically a disk), where they
are kept for later execution. The long-term scheduler, or job scheduler, selects processes from this pool and
loads them into memory for execution.
• Short Term Scheduler (STS): The short-term scheduler, or CPU scheduler, selects from among the processes
that are ready to execute and allocates the CPU to one of them.
• Difference between LTS and STS - The primary distinction between these two schedulers lies
in frequency of execution.
• The short-term scheduler must select a new process for the CPU frequently. A process may
execute for only a few milliseconds before waiting for an I/O request. Often, the short-term
scheduler executes at least once every 100 milliseconds.
• Because of the short time between executions, the short-term scheduler must be fast. The
long-term scheduler on the other hand executes much less frequently; minutes may separate
the creation of one new process and the next.
Degree of Multiprogramming - The number of processes in memory is known as Degree of
Multiprogramming.
• The long-term scheduler controls the degree of multiprogramming as it is responsible for
bringing in the processes to main memory. If the degree of multiprogramming is stable,
then the average rate of process creation must be equal to the average departure rate of
processes leaving the system. So, this means the long-term scheduler may need to be
invoked only when a process leaves the system. Because of the longer interval between
executions, the long-term scheduler can afford to take more time to decide which process
should be selected for execution.
Medium-term scheduler: The key idea behind a medium-term scheduler is that sometimes it
can be advantageous to remove a process from memory (and from active contention for the
CPU) and thus reduce the degree of multiprogramming.
Later, the process can be reintroduced into memory, and its execution can be continued where it
left off. This scheme is called swapping.
The process is swapped out, and is later swapped in, by the medium-term scheduler. Swapping
may be necessary to improve the process mix or because a change in memory requirements has
overcommitted available memory, requiring memory to be freed up.
• Dispatcher - The dispatcher is the module that gives control of the CPU to the process
selected by the short-term scheduler.
• This function involves the following: Switching context, switching to user mode, jumping to
the proper location in the user program to restart that program.
• The dispatcher should be as fast as possible, since it is invoked during every process switch.
The time it takes for the dispatcher to stop one process and start another running is known as
the dispatch latency.
CPU Bound and I/O Bound Processes
• A process execution consists of a cycle of CPU execution or wait and i/o execution or
wait. Normally a process alternates between two states.
• Process execution begin with the CPU burst that may be followed by a i/o burst, then
another CPU and i/o burst and so on. Eventually in the last will end up on CPU burst. So,
process keep switching between the CPU and i/o during execution.
• I/O Bound Processes: An I/O-bound process is one that spends more of its time doing I/O than
it spends doing computations.
• CPU Bound Processes: A CPU-bound process, generates I/O requests infrequently, using more
of its time doing computations.
• It is important that the long-term scheduler select a good process mix of I/O-bound and CPU-
bound processes. If all processes are I/O bound, the ready queue will almost always be empty,
and the short-term scheduler will have little to do.
• Similarly, if all processes are CPU bound, the I/O waiting queue will almost always be empty,
devices will go unused, and again the system will be unbalanced. So, to have the best system
performance LTS needs to select a good combination of I/O and CPU Bound processes.
Context Switch
• When an interrupt occurs, the system needs to save
the current context of the process running on the CPU
so that it can restore that context when its processing
is done.
• Switching the CPU to another process requires
performing a state save of the current process and a
state restore of a different process. This task is known
as a context switch. When a context switch occurs, the
kernel saves the context of the old process in its PCB
and loads the saved context of the new process
scheduled to run. Context-switch time is pure
overhead, because the system does no useful work
while switching.
• Under Pre-emptive scheduling, once the CPU has been allocated to a process, A process will
leave the CPU willingly or it can be forced out. So it will leave the CPU
1. When a process completes its execution
2. When a process leaves CPU voluntarily to perform some i/o operations
3. If a new process enters in the ready states (new, waiting), in case of high priority
4. When process switches from running to ready state because of time quantum expire.
• Scheduling criteria - Different CPU-scheduling algorithms have different
properties, and the choice of a particular algorithm may favour one class of
processes over another. So, in order to efficiently select the scheduling
algorithms following criteria should be taken into consideration:
• CPU utilization: Keeping the CPU as busy as possible.
• 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.
• Waiting time: Waiting time is the sum of the periods spent waiting in the ready queue.
• Response Time: Is the time it takes to start responding, not the time it
takes to output the response.
• Note: The CPU-scheduling algorithm does not affect the amount of time during
which a process executes I/0; it affects only the amount of time that a process
spends waiting in the ready queue.
• Burst Time (BT): Amount of CPU time required by the process to finish its execution.
• Turn Around Time (TAT): Completion Time (CT) – Arrival Time (AT), Waiting Time + Burst Time (BT)
P0 0 100
P1 1 2
Average
P0 1 100
P1 0 2
Average
Convoy Effect
• If the smaller process have to wait more for the CPU because of Larger process then this effect
is called Convoy Effect, it result into more average waiting time.
• Solution, smaller process have to be executed before longer process, to achieve less average
waiting time.
Disadvantage
• FCFS suffers from convoy which means smaller process have to wait larger
process, which result into large average waiting time.
• The FCFS algorithm is thus particularly troublesome for time-sharing systems (due
to its non-pre-emptive nature), where it is important that each user get a share of
the CPU at regular intervals.
• Whenever we make a decision of selecting the next process for CPU execution,
out of all available process, CPU is assigned to the process having smallest burst
time requirement. When the CPU is available, it is assigned to the process that
has the smallest next CPU burst. If there is a tie, FCFS is used to break tie.
• It supports both version non-pre-emptive and pre-emptive (purely greedy
approach)
• In Shortest Job First (SJF)(non-pre-emptive) once a decision is made and among the available
process, the process with the smallest CPU burst is scheduled on the CPU, it cannot be pre-
empted even if a new process with the smaller CPU burst requirement then the remaining
CPU burst of the running process enter in the system.
• In Shortest Remaining Time First (SRTF) (Pre-emptive) whenever a process enters in ready
state, again we make a scheduling decision weather, this new process with the smaller CPU
burst requirement then the remaining CPU burst of the running process and if it is the case
then the running process is pre-empted and new process is scheduled on the CPU.
• This version (SRTF) is also called optimal is it guarantee minimal average waiting
time.
P. No Arrival Time Burst Time Completion Time Turn Around Time Waiting Time
(AT) (BT) (CT) (TAT) = CT - AT (WT) = TAT - BT
P0 1 7
P1 2 5
P2 3 1
P3 4 2
P4 5 8
Average
P. No Arrival Time Burst Time Completion Time Turn Around Time Waiting Time
(AT) (BT) (CT) (TAT) = CT - AT (WT) = TAT - BT
P0 0 6
P1 1 4
P2 2 3
P3 3 1
P4 4 2
P5 5 1
Average
• Advantage
• Pre-emptive version guarantees minimal average waiting time so some time also referred
as optimal algorithm.
• Provide better average response time compare to FCFS
• Disadvantage
• Here process with the longer CPU burst requirement goes into starvation.
• No idea of priority, longer process has poor response time.
Priority scheduling
Traffic on ROAD
Priority scheduling
• Here a priority is associated with each process. At any instance of time out of all
available process, CPU is allocated to the process which possess highest priority (may
be higher or lower number).
• Tie is broken using FCFS order. No importance to senior or burst time. It supports both
non-pre-emptive and pre-emptive versions.
• In Priority (non-pre-emptive) once a decision is made and among the available process,
the process with the highest priority is scheduled on the CPU, it cannot be pre-empted
even if a new process with higher priority more than the priority of the running process
enter in the system.
• In Priority (pre-emptive) once a decision is made and among the available process, the
process with the highest priority is scheduled on the CPU.
• if it a new process with priority more than the priority of the running process enter in
the system, then we do a context switch and the processor is provided to the new
process with higher priority.
P0 1 4 4
P1 2 2 5
P2 2 3 7
P3 3 5 8(H)
P4 3 1 5
P5 4 2 6
Average
P. No AT BT Priority CT TAT = CT - AT WT = TAT - BT
P0 0 50 4
P1 20 20 1(h)
P2 40 100 3
P3 60 40 2
Average
• Advantage
• Gives a facility specially to system process.
• Allow us to run important process even if it is a user process.
• Disadvantage
• Here process with the smaller priority may starve for the CPU
• No idea of response time or waiting time.
• It is similar to FCFS scheduling, but pre-emption is added to enable the system to switch
between processes. The ready queue is treated as a circular queue. The CPU scheduler goes
around the ready queue, allocating the CPU to each process for a time interval equivalent 1
Time quantum (where value of TQ can be anything).
• We fix a time quantum, up to which a process can hold the CPU in one go, with in which either a
process terminates or process must release the CPU and enter the ready queue and wait for the next
chance. The process may have a CPU burst of less than given time quantum. In this case, the process
itself will release the CPU voluntarily.
• CPU Scheduler will select the next process for execution. OR The CPU burst of the currently running
process is longer than 1-time quantum, the timer will go off and will cause an interrupt to the operating
system.
• A context switch will be executed, and the process will be put at the tail of the ready queue. The CPU
scheduler will then select the next process in the ready queue.
• If there are n processes in the ready queue and the time quantum is q, then each process gets 1/n of
the CPU time in chunks of at most q time units.
• Each process must wait no longer than (n - 1) x q time units until its next time quantum.
P. No Arrival Time Burst Time Completion Time Turn Around Time Waiting Time (WT)
(AT) (BT) (CT) (TAT) = CT - AT = TAT - BT
P0 0 4
P1 1 5
P2 2 2
P3 3 1
P4 4 6
P5 6 3
Average
P. No Arrival Time Burst Time Completion Time Turn Around Time Waiting Time (WT)
(AT) (BT) (CT) (TAT) = CT - AT = TAT - BT
P0 5 5
P1 4 6
P2 3 7
P3 1 9
P4 2 2
P5 6 3
Average
• If the time quantum is extremely large, the RR policy is the same as the FCFS policy.
• If the time quantum is extremely small (say, 1 millisecond), the RR approach is called processor
sharing and (in theory) creates the appearance that each of n processes has its own processor
running at 1/n the speed of the real processor. We also need also to consider the effect of
context switching on the performance of RR scheduling.
• Advantage
• Perform best in terms of average response time
• Works will in case of time-sharing systems, client server architecture and interactive
system
• kind of SJF implementation
• Disadvantage
• Longer process may starve
• Performance depends heavily on time quantum - If value of the time quantum is very less,
then it will give lesser average response time (good but total no of context switches will be
more, so CPU utilization will be less), If time quantum is very large then average response
time will be more bad, but no of context switches will be less, so CPU utilization will be
good.
• No idea of priority
Process Synchronization
• As we understand in a multiprogramming environment a good number of
processes compete for limited number of resources.
• Concurrent access to shared data at some time may result in data inconsistency
for e.g.
P ()
{
read ( i );
i = i + 1;
write( i );
}
Race Condition
• The condition in which the output of a process depends on the execution
sequence of process. i.e. if we change the order of execution of different
process with respect to other process the output may change.
3. Hardware Solution
1. Test and Set Lock
2. Disable interrupt
Two Process Solution
• In general it will be difficult to write a valid solution in the first go to solve critical
section problem among multiple processes, so it will be better to first attempt
two process solution and then generalize it to N-Process solution.
• There are 3 Different idea to achieve valid solution, in which some are invalid
while some are valid.
• 3- Peterson’s Solution
• Here we will use a Boolean variable turn, which is initialize randomly(0/1).
P0 P1
while (1) while (1)
{ {
while (turn! = 0); while (turn! = 1);
Critical Section Critical Section
turn = 1; turn = 0;
Remainder section Remainder Section
} }
• The solution follows Mutual Exclusion as the two processes cannot
enter the CS at the same time.
• The solution does not follow the Progress, as it is suffering from the
strict alternation. Because we never asked the process whether it
wants to enter the CS or not?
• Here we will use a Boolean array flag with two cells, where each cell is initialized to F
P0 P1
while (1) while (1)
{ {
flag [0] = T; flag [1] = T;
while (flag [1]); while (flag [0]);
Critical Section Critical Section
flag [0] = F; flag [1] = F;
Remainder section Remainder Section
} }
• This solution follows the Mutual Exclusion Criteria.
Wait(S) Signal(S)
{
{
while(s<=0);
s++;
s--;
} }
• Peterson’s Solution was confined to just two processes, Pi()
and since in a general system can have n processes, {
Semaphores provides n-processes solution. While(T)
{
Initial Section
• While solving Critical Section Problem only we wait(s)
initialize semaphore S = 1. Critical Section
signal(s)
• Semaphores are going to ensure Mutual Exclusion and Remainder Section
}
Progress but does not ensures bounded waiting. }
Wait(S) Signal(S)
{ {
while(s<=0);
s++;
s--;
} }
Q Using Semaphores ensure that the order of execution of there
concurrent process p1, p2 and p3 must be p2 p3 p1?
• Reader-Writer problem
• Both Producer and Consumer can produce and consume only one article at a time.
Producer-Consumer Problem needs to sort out three major issues
• A producer needs to check whether the buffer is overflowed or not after producing an item before accessing the
buffer.
• Similarly, a consumer needs to check for an underflow before accessing the buffer and then consume an item.
• Also, the producer and consumer must be synchronized, so that once a producer and consumer it accessing the
buffer the other must wait.
Solution Using Semaphores
Now to solve the problem we will be using three semaphores:
Semaphore S = 1 // CS
Semaphore E = n // Count Empty cells
Semaphore F = 0 // Count Filled cells
Producer() Consumer()
Semaphore S =
Semaphore E =
Semaphore F =
Total three resources Producer() Consumer()
are used { {
• semaphore E take while(T) while(T)
count of empty cells
{ {
and over flow
• semaphore F take
count of filled cells
and under flow
• Semaphore S take
care of buffer
} }
} }
Total three resources Producer() Consumer()
are used { {
• semaphore E take while(T) while(T)
count of empty cells
{ {
and over flow
// Produce an item
• semaphore F take
count of filled cells
and under flow // Pick item from buffer
• Semaphore S take // Add item to buffer
care of buffer
Consume item
} }
} }
Total three resources Producer() Consumer()
are used { {
• semaphore E take while(T) while(T)
count of empty cells
{ {
and over flow
// Produce an item
• semaphore F take
count of filled cells wait(S)
Wrt =
Readcount =
Writ Reader()
Three resources are used
• Semaphore Wrt is
used for
er() Wait(mutex)
synchronization Readcount++
between WW, WR,
RW
• Semaphore reader is
used to synchronize
between RR Wait(wrt) signal(mutex)
• Readcount is simple
int variable which CS //Write CS //Read
keep counts of
number of readers Signal(wrt) Wait(mutex)
Readcount--
signal(mutex)
Three resources are used Writer() Reader()
• Semaphore Wrt is
used for
Wait(mutex)
synchronization Readcount++
between WW, WR,
RW If(readcount ==1)
• Semaphore reader is
used to synchronize wait(wrt) // first
between RR Wait(wrt) signal(mutex)
• Readcount is simple
int variable which CS //Write CS //Read
keep counts of
number of readers Signal(wrt) Wait(mutex)
Readcount--
If(readcount ==0)
signal(wrt) // last
signal(mutex)
Dining Philosopher Problem
• Scenario Setup: Five philosophers are seated around a circular table,
each with a bowl of rice in the center. The table has five chairs and
five single chopsticks placed between each pair of philosophers.
• Activity Cycle: Philosophers alternate between thinking and eating.
They do not interact with each other while thinking.
• Eating Process:
• A philosopher becomes hungry and attempts to pick up the two
closest chopsticks — one between her and the philosopher on
her left, and one between her and the philosopher on her right.
• Each philosopher can pick up only one chopstick at a time.
• A philosopher cannot pick up a chopstick if it is already being
held by a neighbor.
• Once a philosopher has both chopsticks, she eats without
releasing the chopsticks.
• Post-Eating: After eating, the philosopher puts both chopsticks back
on the table and resumes thinking.
Indian Chopsticks
Solution for Dining Philosophers
Void Philosopher (void)
{
while ( T )
{
Thinking ( ) ;
wait(chopstick [i]);
wait(chopstick([(i+1)%5]);
Eat( );
signal(chopstick [i]);
signal(chopstick([(i+1)%5]);
}
}
• Counting Semaphores: can range over an unrestricted domain Counting semaphore can range
over an unrestricted domain. i.e. -∞ to +∞.
• Counting semaphores can be used to control access to a given resource consisting of a finite
number of instances. The semaphore is initialized to the number of resources available.
• Each process that wishes to use a resource performs a wait() operation on the semaphore
(thereby decrementing the count). When a process releases a resource, it performs a signal()
operation (incrementing the count).
• When the count for the semaphore goes to 0, all resources are being used. After that,
processes that wish to use a resource will block until the count becomes greater than 0.
• Implementation of semaphore This simple implementation of semaphore with this wait(S) and signal(S) function
suffer from busy waiting.
• Modified Wait
• To overcome the need for busy waiting, we can modify the definition of the wait() and signal() operations as
follows: When a process executes the wait() operation and finds that the semaphore value is not >0, it must
wait. However, rather than engaging in busy waiting, the process can block itself. The block operation places
a process into a waiting queue associated with the semaphore, and the state of the process is switched to
the waiting state. Then control is transferred to the CPU scheduler, which selects another process to execute.
wait(semaphore *S)
{
S->value--;
if (S->value < 0)
{
add this process to S->list;
block();
}
}
• Modified Signal
• A process that is blocked, waiting on a semaphore S, should be restarted when some other
process executes a signal() operation. The process is restarted by a wakeup() operation,
which changes the process from the waiting state to the ready state. The process is then
placed in the ready queue. (The CPU may or may not be switched from the running
process to the newly ready process, depending on the CPU-scheduling algorithm.)
Signal(semaphore *S)
{
S->value++;
if (S->value <= 0)
{
remove a process P from S->list;
wakeup(P);
}
}
To implement semaphores under this definition, we define a semaphore as follows:
typedef struct
{
int value;
struct process *list;
} semaphore;
• Note that in this implementation, semaphore values may be negative, whereas semaphore
values are never negative under the classical definition of semaphores with busy waiting. If a
semaphore value is negative, its magnitude is the number of processes waiting on that
semaphore. This fact results from switching the order of the decrement and the test in the
implementation of the wait() operation.
• The list of waiting processes can be easily implemented by a link field in each process control
block (PCB). Each semaphore contains an integer value and a pointer to a list of PCBs. One way
to add and remove processes from the list so as to ensure bounded waiting is to use a FIFO
queue, where the semaphore contains both head and tail pointers to the queue.