OS Chapter Two
OS Chapter Two
Process Management
2.1 Overview
The most fundamental task of modern operating systems is process management. It includes
o Creating processes
o Allocating resources to processes
o Managing conflicting demands
o Protecting resources of each process from other processes
o Enabling processes to share and exchange information
o Enabling synchronization among processes for proper sequencing and coordination when dependencies exist
o Termination processes
The most central concept in operating system is a process
o A process may have inputs and outputs
o A process resides in memory
o A process may access files
2.2 Process Concept
2.2.1 Process vs. Program
o Program
It is sequence of instructions defined to perform some task
It is a passive entity
o Process
It is a program in execution
It is an instance of a program running on a computer
It is an active entity
A processor performs the actions defined by a process
2.2.2 Types of Processes
o There are two types of processes
Sequential Processes
Execution progresses in a sequential fashion, i.e. one after the other
At any point in time, at most one process is being executed
Concurrent Processes
There are two types of concurrent processes
True Concurrency (Multiprocessing)
- Two or more processes are executed simultaneously in a multiprocessor environment
- Supports real parallelism
Apparent Concurrency (Multiprogramming)
- Two or more processes are executed in parallel in a uniprocessor environment by
switching from one process to another
- Supports pseudo parallelism, i.e. the fast switching among processes gives illusion of
parallelism
In both cases if a snapshot of the system is taken, several processes will be found in a state
of partial execution
o Real life example: Consider a computer scientist who is baking a birthday cake for her daughter and who is
interrupted by her daughter’s bleeding accident
1
Analysis
Processes Baking Cake First Aid
Processor Computer Scientist Computer Scientist
Program Recipe First Aid Book
Input Ingredients First Aid Kit
Output Cake First Aid Service
Priority Higher Lower
States Running, Idle Running, Idle
Sequence of actions
Bringing ingredients i.e. flour, sugar, eggs, etc
Placing the mixture into the oven
Following the baking processes
Hearing a cry and analyzing it to be because of bleeding
Recording baking processes state and switching to provide first aid service
Providing first aid service
Coming back and resuming the baking process
2.2.3 Process States
a. Process States
o During its lifetime, a process passes through a number of states. The most important states are: Ready,
Running, Blocked (waiting)
New
A process that has just been created but has not yet been admitted to the pool of executable
processes by the operating system
Information concerning the process is already maintained in memory but the code is not
loaded and no space has been allocated for the process
Ready
A process that is not currently executing but that is ready to be executed as soon as the
operating system dispatches it
Running
A process that is currently being executed
Blocked (Waiting)
A process that is waiting for the completion of some event, such as and I/O operation
Exit (Terminated)
A process that has been released from the pool of executable processes by the operating
system, either because it halted or because it aborted for some reason
Information associated with the process are temporarily preserved by the operating system
until auxiliary or support programs extract any needed information, for instance for
performance monitoring or billing purpose
release
New admit Ready dispatch Running Exit
Blocked
2
b. Process State Transitions
o The main process state transitions are
Null New
It occurs when a new process is created to execute a program
New Ready
It occurs when the operating system is prepared to take on additional process and a new
process is admitted
Ready Running
It occurs when the operating system chooses one of the processes in the ready state for
running
The process is called dispatching and it is caused by the dispatcher (scheduler)
Dispatch (process name)
Running Blocked
It occurs when a process requests something for which it must wait
Examples
- Request for an I/O operation
- Request for a file
- Request for another process to produce input
- Request for another process to produce a message
- Request for a shared section of a virtual memory
- Wait (process name)
Blocked Ready
It occurs when the event for which a process has been waiting occurs
Wakeup (process name)
Running Ready
It occurs when a process is preempted by the operating system
Examples
- When time is expired
- When a blocked process with higher priority is moved to ready state
- Timeout (process name)
Running Exit
It occurs when a currently running process is terminated
Halt (process name) or Abort (process name)
o The operating system manages ready and blocked processes using queue data structures
Ready Queue
Processor release
admit ... Dispatch
Time-out
Event
Blocked Queue Event wait
Occurs
...
o To improve performance multiple ready and blocked queues can be used
Multiple blocked queues are used to categorize blocked processes based on events
Multiple ready queues are used to categorize ready processes based on priorities
3
2.2.4 Process Description
a. Control Tables
o If the operating system is to manage processes and resources, it must have information about the current
status of each process and resources
o The operating system constructs and maintains tables of information, called control tables
o There are four major control tables
Memory tables
Used to keep track of both main and virtual memory
Include information about
- Allocation of main memory to processes
- Allocation of secondary memory to processes
- Any protection attributes of blocks of memory
- Any information needed to manage virtual memory
I/O tables
Used to manage the I/O devices and channels of computer system
Include information about
- Status of I/O devices: available/assigned
- Status of I/O operation
- Main memory being used as a source or destination of the I/O transfer
File tables
Used to manage files
Include information about
- Existence of files
- Location of files on secondary memory
- Current status of files
- Other attributes of files
Process tables
Used to manage processes
Include information about
- Location of each process
- Attributes of each process
o The tables must be linked or cross-referenced in some fashion
o The operating system must have some knowledge of the basic environment of the computer system
Amount of main and virtual memories
I/O devices available
b. Process Image
o It is the physical manifestation of each process. It consists of two parts
Address space
Memory space within which the process executes. It consists of
- Program: code of the program to be executed
- Data: data locations for local and global variables and any defined constants
- System stack: used to keep track of procedure calls and parameter passing between
procedures
PCB (Process Control Block)
Contains all information that is required by the operating system to manage a process
It consists of the following categories of information
- Process Identification
Process identifier
4
Parent identifier
User identifier
- Processor State Information
User visible registers (AX, BX, CX, DX, SI, DI etc)
Control status register (PSW, PC)
Stack pointer (SP, BP)
- Process Control Information
Scheduling and state information: process state, priority, event
Data structuring: pointers to other processes
Interprocess communication: flags, signals, messages
Process privileges: memory access, instructions, utilities and services
Memory management: pointers to segments and / or page tables
Resource ownership and utilization: resources controlled, resource utilization
history
It is the most important data structure in an operating system
It is accessed virtually by every module in the operating system
All PCBs are linked to form a list. Which is accessed by a pointer in a central table
Process Image1
Memory Memory tables Address
Space 1
Devices I/O tables PCB 1
Process 1 PCB 2
Process 2 .
. .
. .
.
Process Imagen
.
Process n Address
.
General structure of operating system control tables Space n
.
PCB n
2.2.5 Process Switching
o Process switch occurs when a running process is interrupted and the operating system assigns another
process to the running state and turns control over to that process
o Process switch is sometimes called context switch
o A running process may be interrupted by
Interrupt: An event that occurs outside the process and that is recognized by the processor
(clock interrupt, I/O interrupt)
Supervisor Call: A procedure call used by user programs to call an operating system function
Trap: An error or exception condition generated within the currently running process (illegal file
access attempt)
o If an interrupt is pending, the processor does the following
It saves the context of the current process
It sets the program counter to the starting address of an interrupt handler program
It switches the processor mode from user mode to kernel mode so that the interrupt processing
code may include privileged instructions
o The occurrence of an interrupt results in mode switch but does not necessarily mean a process switch
i.e. a mode switch may occur without changing the state of the process that is currently running
5
o If the interrupt is handled and the operating system has decided to move the currently running process
to another state, process switch occurs
o Steps involved in each process switch are
Save the context of the processor
Update the PCB of the process that is currently in running state
Move the PCB of this process to the appropriate queue
Update the PCB of the process selected
Update the memory management data structures
Restore the context of the processor to that which existed at the time the selected process was
last switched out of running state
o Process switch (dispatch latency) is an overhead and its speed depends on the hardware: 1 to 100 ms
o Process switch is sometimes a performance bottleneck
2.2.6 Threads
o Thread vs. Process
A thread is a dispatchable unit of work (lightweight process) that has independent context, state
and stack
A process is a collection of one or more threads and associated system resources
Traditional operating systems are single-threaded systems
Modern operating systems are multithreaded systems
o Multithreading
Multithreading is a technique in which a process, executing an application, is divided into
threads that can run concurrently
Handling several independent tasks of an application that do not need to be serialized
(e.g. database servers, web servers)
Having great control over the modularity of the application and the timing of application
related events
Each thread has independent context, state and stack
All threads share the same address space and a separate thread table is needed to manage the
threads
Threads can be managed in the kernel or user space
Kernel Space
- The operating system is aware of the existence of multiple threads
- When a thread blocks, the operating system chooses the next one to run, either
from the same process or a different one
- The kernel has a thread table
- Thread management is slow
User Space
- The operating system is not aware of the existence of multiple threads
- When a thread is about to block, it chooses and starts its successor before
stopping
- The user space has a thread table
- Thread management is much faster (specially switching)
- When one thread blocks, the kernel blocks the entire process
Both systems are in use and various hybrid schemes have been proposed as well
Introducing threads into an existing system needs a substantial system redesign
6
2.3 Processor Scheduling
2.3.1 Processor Scheduling Concept
o Scheduling refers to a set of policies and mechanisms to control the order of work to be performed by a
computer system. Of all the resources of a computer system that are scheduled before use, the
CPU/processor is the far most important.
o Processor Scheduling is the means by which operating systems allocate processor time for processes.
o The operating system makes three types of scheduling decisions with respect to execution of processes:
Long-term Scheduling
The decision to add to the pool of processes to be executed
It determines when new processes are admitted to the system
It is performed when a new process is created and admitted
Medium-term Scheduling
The decision to add to the number of processes that are partially/fully in main memory
It determines when a program is brought partially or fully into main memory so that it may be
executed
It is performed when swapping is done
Short-term Scheduling
The decision of which ready process to execute next
It determines which ready process will get processor time next
It is performed when a ready process is allocated the processor (when it is dispatched)
o Part of the operating system that makes scheduling decision is called scheduler and the algorithm it uses is
called scheduling algorithm
o In the case of short term scheduling, the module that gives control of CPU to the process selected by the
scheduler is called dispatcher. Its functions are
Process switch (Context Switch)
Mode Switch: Kernel User
Control branching: to the proper location in the user program
o There are some requirements that should be met by short-term schedulers/scheduling algorithms. Some of
these requirements are user-oriented, which relate to the behavior of the system as perceived by the
individual user or process and the rest are system-oriented, which focus on effective and efficient utilization
of the processor
Response Time: For interactive users, the time from submission of request until the response begins
to be received should be minimized
Turn Around Time: For batch users, the interval of time between the submission of a process and its
completion should be minimized
Throughput: The number of processes completed per unit time should be maximized
Fairness: Each process should get its fair share of the CPU. No process should suffer starvation
Predictability: A given process should run in about the same amount of time and at about the same
cost regardless of the load of the system
Efficiency/CPU Utilization: The percentage of time that the CPU is busy should be maximized
o Scheduling requirements are interdependent and some of them are contradictory and hence it is impossible to
optimize all of them simultaneously. For instance minimizing response time requires frequent switching which
increases the overhead of the system and so reduces throughput
o The design of scheduling policy involves compromising among competing requirements
o There are two main characteristics of short-term scheduling algorithms
7
Selection function
It determines which process, among ready processes, is selected for execution
It may be based on
- Priority
- Resource requirement
- Execution behavior: time spent in system so far (waiting and executing), time spent in
execution so far, total service time required by the process
Decision mode
It specifies the instants in time at which the selection function is exercised
There are two types of decision modes
- Preemptive
The strategy of allowing processes that are logically runnable to be temporarily
suspended and be moved to the ready state. Events that may result pre-emption
are arrival of new processes, occurrence of an interrupt that moves blocked
process to ready state and clock interrupt
Suitable for general purpose systems with multiple users
Guarantees acceptable response time and fairness
Context switching is an overhead
- Non-Preemptive
Run to completion method: once a process is in running state, it continues to
execute until it terminates or blocks itself to wait for some event
Simple and easy to implement
Used in early batch systems
It may be well reasonable for some dedicated systems
Efficiency can be attained but response time is very high
8
Case ii. If they arrive in the order of P3, P2, P1
Process P3 P2 P1
Service Time (Ts) 3 3 24
Turn around time (Tr) 3 6 30
Response time 0 3 6
Tr/Ts 1 2 1.25
Average response time = (0+3+6)/3 = 3
Average turn around time = (3+6+30)/3=13
Throughput = 3/30= 1/10
o Consider the following processes arrive at time 0, 1, 2, 3 respectively
Process P1 P2 P3 P4
Arrival Time (Ta) 0 1 2 3
Service Time (Ts) 1 100 1 100
Turn around time (Tr) 1 100 100 199
Response time 0 0 99 99
Tr/Ts 1 1 100 1.99
Average response time = (0+0+99+99)/4 = 49.5
Average turn around time = (1+100+100+199)/4=100
Throughput = 4/202
Advantages
o It is the simplest of all non-preemptive scheduling algorithms: process selection & maintenance of
the queue is simple
o There is a minimum overhead and no starvation
o It is often combined with priority scheduling to provide efficiency
Drawbacks
o Poor CPU and I/O utilization: CPU will be idle when a process is blocked for some I/O operation
o Poor and unpredictable performance: it depends on the arrival of processes
o Unfair CPU allocation: If a big process is executing, all other processes will be forced to wait for a
long time until the process releases the CPU. It performs much better for long processes than short
ones
o Process with the shortest expected processing time (CPU burst) is selected next
o Its selection function is execution time and it uses non preemptive scheduling/decision mode
Illustration
o Consider the following processes arrive at time 0
Process P1 P2 P3
CPU Burst (in ms) 24 3 3
Case i. FCFSS
Process P1 P2 P3
Turn around time 24 27 30
Response time 0 24 27
Average response time = (0+24+27)/3 = 17
Average turn around time = (24+27+30)/3=27
Throughput = 3/30
9
Case ii. SJFS
Process P3 P2 P1
Turn around time 3 6 30
Response time 0 3 6
Average response time = (0+3+6)/3 = 3
Average turn around time = (3+6+30)/3=13
Throughput = 3/30
10
Illustration
o Consider the following processes arrive at time 0, 2, 4, 6, 8 respectively
Process P1 P2 P3 P4 P5
Arrival Time (Ta) 0 2 4 6 8
Service Time (Ts) 3 6 4 5 2
Turn around time (Tr) 3 13 4 14 2
Response time 0 1 0 9 0
Tr/Ts 1 2.17 1 2.8 1
Average response time = (0+1+0+9+0)/5 = 2
Average turn around time = (3+13+4+14+2)/5=7.2
Throughput = 5/20
Advantages
o It gives superior turnaround time performance to SJFS, because a short job is given immediate
preference to a running longer process
Drawbacks
o There is a risk of starvation of longer processes
o High overhead due to frequent process switch
Difficulty with SJFS
o Figuring out required processing time of each process
d. Round Robin Scheduling (RRS)
Basic Concept
o A small amount of time called a quantum or time slice is defined. According to the quantum, a
clock interrupt is generated at periodic intervals. When the interrupt occurs, the currently
running process is placed in the ready queue, and the next ready process is selected on a
FCFS basis.
o The CPU is allocated to each process for a time interval of upto one quantum. When a process
finishes its quantum it is added to the ready queue, when it is requesting I/O it is added to the
waiting queue
o The ready queue is treated as a circular queue
o Its selection function is based on quantum and it uses preemptive decision mode
Illustration
o Consider the following processes arrive at time 0, 2, 4 respectively
Process P1 P2 P3
Arrival Time (Ta) 0 2 4
Service Time (Ts) 3 7 4
Turn around time (Tr)
Response time
Tr/Ts
Average response time =
Average turn around time =)
Throughput = 3/14
Features
o The oldest, simplest, fairest and most widely used preemptive scheduling
o Reduces the penalty that short processes suffer with FCFS
Drawbacks
o CPU-bound processes tend to receive unfair portion of CPU time, which results in poor
performance for I/O bound processes
o It makes implicit assumption that all processes are equally important. It does not take external
factors into account
o Maximum overhead due to frequent process switch
11
Difficulty with RRS
o The length of the quantum should be decided carefully
E.g.1 quantum =20ms, context switch =5ms, % of context switch = 5/25 *100=20%
Poor CPU utilization
Good interactivity
E.g.1 quantum =500ms, context switch =5ms, % of context switch = 5/505 *100<1%
Improved CPU utilization
Poor interactivity
Setting the quantum too short causes
Poor CPU utilization
Good interactivity
Setting the quantum too long causes
Improved CPU utilization
Poor interactivity
A quantum around 100ms is often reasonable compromise
o To enable interactivity, a maximum response time (MR) can be specified, and the quantum (m)
can be computed dynamically as follows
m = MR/n , where n is number of processes
A new m is calculated when the number of processes changes
Not to allow m to be very small
Fix a minimum quantum (min_time_slice) and choose the maximum of MR/n and
min_time_slice: m = max (MR/n, min_time_slice)
Use biased round robin that gives extra service to high priority processes: e.g. process k is
given a time slice of m k
mk = max (pkMR/pi , min_time_slice) , where pi is the priority of process I
and bigger pi means higher priority
e. Priority Scheduling (PS)
Basic Concept
o Each process is assigned a priority and the runnable process with the highest priority is allowed
to run i.e. a ready process with highest priority is given the CPU.
o It is often convenient to group processes into priority classes and use priority scheduling among
the classes but round robin scheduling within each class
Illustration
o Consider the following processes arrive at time 0
Process P1 P2 P3 P4 P5
Priority 2 4 5 3 1
Service Time (Ts) 3 6 4 5 2
Turn around time (Tr) 18 10 4 15 20
Response time 15 4 0 10 18
Tr/Ts 6 1.67 1 3 10
Average response time = (0+15+4+10+18)/5 = 9.4
Average turn around time = (18+10+4+15+20)/5=13.4
Throughput = 5/20= 0.25
o Consider the following priority classes
Processes type: Deans Heads Instructors Secretaries Students
Priority: 5 4 3 2 1
As long as there are runnable processes in priority level 5, just run each
one for one quantum, round robin fashion, and never bother with lower
priority classes
12
If priorities are not adjusted occasionally, lower priority classes may all
starve to death
Advantages
o It considers the fact that some processes are more important than others, i.e. it takes external
factors into account
Drawbacks
o A high priority process may run indefinitely and it can prevent all other processes from running.
This creates starvation on other processes. There are two possible solutions for this problem:
Assigning a maximum quantum to each process
Assigning priorities dynamically, i.e. avoid using static priorities
Assigning a process a priority of 1/q where q is the fraction of the last quantum that is
used
- A process that used only 2ms of its 100ms quantum would get a priority of
50=1/2/100
- A process that used 50ms of its 100ms quantum would get a priority of
2=1/50/100
Decreasing the priority of the currently running process at each clock tick
13
There is nothing shared between processes
Processes are aware of each other directly
C. Concurrency Problems
There are some serious problems associated with the interaction of concurrently running processes:
i. Race Condition
A situation that occurs when two or more processes are reading or writing into some shared data and
the final result depends on who runs precisely when
E.g. 1 Printer Spooler: when a process wants to print a file, it enters the file name in a special spooler
directory. Assume that the spooler directory has a large number of slots, numbered 0,1,2,…
There are two globally shared variables
Outfile: points to the next file to be printed
Infile: points to the next free slot in the directory
There were some files in the spooler directory and assume the current value of infile is 7 and that
of outfile is 3
Assume that simultaneously process A and process B decide they want to queue a file for printing
- Process A reads infile and stores the value 7 in its local variable (x=infile)
- An interrupt occurs and the CPU decides that process A has run long enough so it switches
to process B
- Process B reads infile and stores the value 7 in its local variable (y=infile)
- Process B stores the name of its file in slot 7 and adjusts infile to be 8
- Eventually process A runs again, it checks x and finds 7 there, and writes its file name in
slot 7, erasing the name process B just put there, it updates infile to be 8
- The printer daemon will now print the file of process A, process B file will never get any
output
E.g. 2 Character echo procedure: consider the following globally shared procedure
Void echo
{
chin=getchar(); //read a character from keyboard
chout=chin;
putchar (chout); //display the character on the screen
}
Consider two processes (P1 & P2) trying to access the procedure
- Process P1 invokes the echo procedure and is interrupted immediately after the conclusion
of getchar function (chin =x)
- Process P2 is activated and invokes the echo procedure, which runs to conclusion,
inputting an displaying a single character, y
- Process P1 is resumed. By this time the value x ihas been overwritten in chin and therefore
lost. Instead chin contains y, and is displayed twice
ii. Deadlock
It is the permanent blocking of a set of processes that either compete for system resources or
communicate with each other. It involves conflicting needs for resources by two or more processes.
It refers to a situation in which a set of two or more processes are waiting for other members of the set
to complete an operation in order to proceed, but none of the members is able to proceed.
E.g. Traffic deadlock: consider a situation in which four cars have arrived at a four-way stop
intersection at the same time. The four quadrants of the intersection are the resources over which
control is needed. If all four cars proceed into the intersection, then each car controls one resource
(one quadrant) but cannot proceed because the required second resource has already been
controlled by another car. Hence deadlock will occur. The main reason for this deadlock is because
each car needs exclusive use of both resources for certain period of time
It is a difficult phenomenon to anticipate and there are no easy general solutions to this problem
14
iii. Starvation
It referees to the situation in which a process is ready to execute but is continuously denied access to
a processor in deference to other processes.
E.g. suppose that there are three processes P1, P2, and P3 and each require periodic access to
resource R. If the operating system grants the resource to P1 and P2 alternately, P3 may indefinitely
be denied access to the resource, thus starvation may occur.
In large part, it is a scheduling issue
D. Mutual Exclusion
The key to preventing race condition is to enforce mutual exclusion: It is the ability to exclude
(prohibit) all other processes from using a shared variable or file while one process is using it.
Part of a program where shared resource (critical resource) is accessed is called critical region or
critical section
Process A Process B
- -
- - Non-Critical Section
- -
Read infile Read infile
Put file Put file Critical Section
Increment infile Increment infile
- -
- - Non-Critical Section
- -
The fundamental strategy for implementing mutual exclusion is avoiding the situation where no two
processes could ever be in their critical regions at the same time.
There are some basic requirements that should be met while implementing mutual exclusion
i. No two processes may be simultaneously in their critical regions
ii. No assumptions may be made about speed or the number of processors
iii. No process running outside its critical region may block other processes
iv. No process should have to wait forever to enter its critical region
B. Lock Variables
o Assume we have a single shared (lock) variable initially set to 0
o A process enters its critical section if this variable is 0, when it enters it sets it to 1
o If the lock is already 1, the process waits until it becomes 0
15
o Thus a 0 means that no process is in its critical region, and a 1 means that some process is in its critical
region
o Disadvantages
Suppose that one process reads the lock and sees that it is 0. Before it can set the lock to 1, another
process is scheduled, runs and sets the lock to 1. when the first process runs again, it will also set the
lock to 1 and the two processes will be in their critical region at the same time causing race condition
Continuously testing a variable waiting for some value to appear is called busy waiting. This technique
wastes processor time
C. Strict Alternation
o Strict alternation is shown in the program fragment below for two processes, process 0 and process 1. This
solution requires that the two processes strictly alternate in entering their critical regions.
While (TRUE) {
While (TRUE) { While(turn!=1) /*wait*/;
While(turn!=0) /*wait*/; Critical_region();
Critical_region(); turn=0;
turn=1; Noncritical_region();
Noncritical_region(); }
}
o The integer turn, initially 0, keeps track of whose turn it is to enter the critical region and examines or
updates the shared memory
o Initially, process 0 inspects turn, finds it to be 0, and enters its critical region. Process 1 also finds to be
0 and therefore sits in a tight loop continually testing turn to see when it becomes 1. When process 0
leaves the critical region, it sets turn to 1, to allow process 1 to enter its critical region.
o Disadvantages
Taking turns is not a good idea when one of the processes is much slower than the other. This
situation violates condition 3 of implementing mutual exclusions: process 0 is being blocked by
a process not in its critical region.
D. Peterson’s Solution
o It is a software solution. It combines the idea of taking turns with the idea of lock variables and warning
variables. It does not require strict alternation.
o Before using the shared variable, i.e. before entering its critical region, each process calls enter_region
procedure with its own process number, 0 or 1 as a parameter. This call will cause it to wait, if need be,
until it is safe to enter. After it has finished with the shared variables, the process calls leave_region
procedure to indicate that it is done and to allow the other process to enter, if it so desires. The code is
shown below:
16
#define FALSE 0
#define TRUE 1
#define N 2 /* number of processes*/
int turn; /*whose turn is it?*/
int interested[N]; /*all values initially 0 (FALSE)*/
void enter_region (int process) /*process is 0 or 1*/
{
int other; /*number of the othe process*/
other = 1-process; /*the opposite of the process*/
interested[process] = TRUE; /*show that you are interested*/
turn = process; /* set flag*/
while (turn ==process && interested[other]=TRUE); /*null statement*/
}
void leave_region (int process) /*process who is leaving*/
{
interested[process] = FALSE;
}
o Initially, neither process is in its critical section. Now process 0 calls enter_region. It indicates its interest
by setting its array element & sets turn to to 0. Since process 1 is not interested, enter_region returns
immediately. If process 1 now calls enter_region, it will hang there until interested[0] goes to false, an
event that only happens when process 0 calls leave_region to exit the critical region.
o Now consider the case that both processes call enter_region almost simultaneously. Both will store
their process number in turn. Whichever store is done last is the one that counts; the first one is lost.
Suppose that process 1 stores last, so turn is 1. When both processes come to the while statement,
process 0 executes it zero times and enters its critical section. Process 1 loops and does not enter its
critical section.
E. TSL Instruction
o This technique requires a little help from the hardware. It uses the hardware instruction TSL.
o TSL (Test and Set Lock) is an indivisible atomic instruction that copies the content of a memory location
into a register and stores a non-zero value at the memory location. The operation of reading the word
and storing into it are guaranteed to be indivisible, i.e. no other processor can access the memory word
until the instruction is finished. The processor executing the TSL instruction locks the memory bus to
prohibit other processors from accessing the memory until it is done.
o To implement mutual exclusion with TSL instruction, we use a shared variable, lock, to coordinate
access to shared memory. When lock is 0 the process may set it to 1 using TSL instruction and
executes its critical section. When it is done, the process sets lock into 0.
enter_region:
TSL register, lock ;copy lock to register and set lock to 1
CMP register, #0 ;was lock 0?
JNE enter region ;if it was non zero, lock was set, so loop
RET ;return to caller, critical region entered
leave_region:
MOV lock, #0 ;store 0 in lock
RET ;return to caller
19
o Before entering its critical region, a process calls enter_region, which does busy waiting until the lock is
free; then it acquires the lock and returns. After the critical region the process calls leave_region, which
stores a 0 in lock.
o Producer-consumer problem
Two processes share a common fixed-size buffer. One of, the producers, puts information in
the buffer, and the other one, the consumer, takes it out.
When the producer wants to put a new item in the buffer, it checks the buffer, if it is full, it goes
to sleep, to be awakened when the consumer has removed one or more items.
When the consumer wants to remove an item from the buffer and sees that the buffer is empty,
it goes to sleep until the producer puts something in the buffer and wakes it up.
Let us see the producer-consumer problem using c programming
20
void consumer ()
{
while (TRUE)
{
if(count==0) sleep(); /*if buffer is empty, go to sleep*/
item=remove_item(); /*take item out of buffer*/
count=count-1; /*decrement count of items in buffer*/
if(count==N-1) wakeup(producer); /*was buffer full?*/
consume_item(item); /*print item*/
}
}
Problem:
Race condition can occur because access to count is unconstrained. Consider the
following situation. The buffer is empty and the consumer has just read count to see if it
is 0. At that instant, the scheduler decides to stop running the consumer temporarily
and start running the producer. The producer enters an item in the buffer, increments
count, and notices that it is now 1. Reasoning the count was just 0, and thus the
consumer must be sleeping, and the producer calls wakeup to wake the consumer up.
Unfortunately, the consumer is not yet logically asleep, so the wakeup signal is lost.
When the consumer next runs, it will test the value of count it previously read, find it to
be 0, and go to sleep. Sooner or later the producer will fill up the buffer and also go to
sleep. Both will sleep forever.
The problem arises because the wakeup signal is lost. A quick fix is to add to the rules
by adding wakeup-waiting bit. It is a piggy bank for wakeup signals
- When a wakeup is sent to a process that is still awake, this bit is set. Later,
when the process tries to go to sleep, if the wakeup-waiting bit is on, it will be
turned off, but the process will stay awake.
- The wakeup waiting bit cannot be a general solution, especially for any random
number of processes.
A. Semaphores
o Semaphores solve the lost-wakeup problem
o A semaphore is a new integer variable type that counts the number of wakeups saved for future use. A
semaphore could have the value 0, indicating that no wakeups were saved or some positive value if
one or more wakeups were pending.
o Two operations were proposed to implement semaphores: up and down
DOWN operation
It checks the value of the semaphore to see if the value is greater than 0. If so it
decrements the value and just continues. If the value is 0, the process is put to sleep
without completing the DOWN operation for the moment
Checking the value, changing it and going to sleep is all done as a single, indivisible
atomic operation. Once a semaphore operation has started, no other process can
access the semaphore until the operation has completed or blocked
UP operation
It increments the value of the semaphore. If one or more processes were sleeping on
that semaphore, unable to complete an earlier DOWN operation, one of them is chosen
by the system and is allowed to complete its DOWN operation
The process of incrementing the semaphore and waking up one process is also
indivisible.
21
Semantics of DOWN and UP operations
Void DOWN(s:semaphore)
{
if(s==0) sleep();
s=s-1;
}
Void UP(s:semaphore)
{
s=s+1;
wakeup a sleeping process if any;
}
void consumer ()
{
int item;
while (TRUE) {
down(&full); /*decrement full count*/
down(&mutex); /*enter critical section*/
item=remove_item(&item); /*take item from buffer*/
up(&mutex); /*leave critical section*/
up(&empty); /*increment count of empty slots*/
consumer_item(item); /*do something with the item*/ }
}
The solution uses three semaphores: full, to count the number of full slots, empty, to count the
number of empty slots and mutex, to make sure the producer and the consumer do not access
the buffer at the same time
Mutex is used for mutual exclusion, i.e. it is designed to guarantee that only one process at a
time will be reading or writing the buffer and the associated variables
22
Full/empty are used for synchronization, i.e. they are designed to guarantee that certain event
sequences do or do not occur
The producer stops running when the buffer is full, and the consumer stops running when it is
empty.
Semaphores that are initialized to 1 and are used by two or more processes to ensure that only
one of them can enter its critical region at the same time are called binary semaphores
o Problems
Semaphores are too low-level and error prone. If you are not careful when using them, errors
like race condition, deadlocks and other forms of unpredictable and irreproducible behavior can
occur
Suppose that the two downs in the producer’s code were interchanged or reversed in order and
suppose also the buffer was full and mutex is 1
down (&mutex);
down (&empty);
The producer does a down on mutex and mutex becomes 0 and then the producer does a
down on empty. The producer would block since the buffer is full. Next time the consumer does
a down on mutex and it blocks since mutex is 0. Therefore both processes would block forever
and hence deadlock would occur.
B. Monitors
o A monitor is a higher level of synchronization primitive proposed by Hoare and Branch Hansen to make
writing a correct program easier.
o A monitor is a collection of procedures, variables and data structures that are all grouped together in a
special kind of module or package.
o Rules associated with monitors
Processes may call the procedures in a monitor whenever they want to, but they can not
directly access the monitor’s internal data structures
Only one procedure can be active in a monitor at any instant. Monitors are programming
language construct, so the compiler knows that they are special and can handle calls to a
monitor procedures differently from other procedure calls
It is the compiler that implements mutual exclusion. The person writing the monitor does not
have to be aware of how the compiler arranges for mutual exclusion. It is sufficient to know that
by turning all critical regions into monitor procedure, no two processes will ever execute their
critical regions at the same time.
o Monitors use condition variables, along with two operations on them, WAIT and SIGNAL to block and
wake up a process.
WAIT
When a monitor procedure discovers that it can not continue, it does a WAIT on some
condition variable that causes the calling procedure to block.
It allows another process that had been previously prohibited from entering the monitor
to enter now.
SIGNAL
A process can wake up its sleeping partner by doing a SIGNAL on the condition
variable that its partner is waiting on
A process doing a SIGNAL statement must exit the monitor immediately, i.e. SIGNAL
will be the final statement in a monitor procedure. This avoids having two active
processes in a monitor at the same time.
If a SIGNAL is done on a condition variable on which several processes are waiting,
only one of them, determined by the system scheduler is revived.
23
Condition variables are not counters. They do not accumulate signals for later use, unlike
semaphores. If a condition variable is signaled with no one waiting on it, the signal is lost.
The WAIT must always come before the SIGNAL
o WAIT and SIGNAL are similar to SLEEP and WAKEUP but with one critical difference. SLEEP and
WAKEUP failed because while one process was trying to go to sleep, the other one was trying to wake
it up. With monitors, this cannot happen. The automatic mutual exclusion on monitor procedures
guarantees that if, say, the procedure inside a monitor discovers that the buffer is full, it will be able to
complete the WAIT operation without having to worry about the possibility that the scheduler may
switch to the consumer just before the WAIT completes.
o Advantage of monitors
By making mutual exclusion of critical regions automatic, monitors make parallel programming
much less error prone than with semaphores
o Drawback of monitors
You need a language that has built-in monitors, but languages that have built-in monitors are
rare. But adding semaphores in C, C++ and other languages is easy.
o Drawback of monitors and semaphores
They were designed for solving the mutual exclusion problem on one or more CPUs that all
have access to a common memory
In a distributed system consisting of multiple CPUs, each with its own private memory,
connected by a local area network, these primitives become inapplicable
24
Semaphores are too low level and monitors are not usable except in a few programming
languages. And none of them provide information exchange between machines
B. Message Passing
o This technique uses two primitives: SEND and RECEIVE
o SEND and RECEIVE are system calls and they can be put as library procedures: SEND(dest, &msg),
RECEIVE(source, &msg)
o If no message is available, the receiver could block until one arrives or could return with an error code
o The producer-consumer problem with message passing
An outline for the solution of producer-consumer problem with message passing is shown below
#define N 100
void producer()
{
int item;
message m;
while (TRUE) {
produce_item(&item);
receive(consumer, &m);
build_message(&m, item);
send(consumer, &m); }
}
void consumer()
{
int item, i;
message m;
for(I=0;I<N;I++) send (producer, &m);
while(TRUE) {
receive(producer, &m);
extract_item(&m, &item);
send(producer, &m);
consume_item(item);
}
}
All messages are of the same size
Messages sent are buffered automatically by the operating system
The consumer starts out by sending N empty messages
Whenever the producer has an item to give to the consumer, it takes an empty message and
sends back a full one
If the producer works faster
All messages will end up full, waiting for the consumer
The producer will be blocked, waiting for an empty messages to comeback
If the consumer works faster
All the messages will be empties waiting for the producer to fill them up
The consumer will be blocked, waiting for a full message
o Message passing variants (How messages are addressed?)
Using process address
Assigning each process a unique address and have messages be addressed to
processes
Using mailbox
25
A mailbox is a place to buffer certain number of messages, typically specified when the
mailbox is created
The address parameters in SEND and RECEIVE calls are mailboxes not processes
The producer sends messages containing data to the consumer’s mailbox and the
consumer sends empty messages to the producer’s mailbox
Rendezvous (Eliminate buffering)
SEND is done before RECEIVE
The sending process is blocked until the receive happens at which time the message
can be copied directly from the sender to the receiver, with no intermediate buffering
If the receive is done first, the receiver is blocked until a send happens
It is easier to implement
It is less flexible since the sender and receiver are forced to run in lock stop
o Design issues for message passing
Messages can be lost. The solution for this problem is using acknowledgement message
Acknowledgement message can be lost. The solution for this problem is to put consecutive
sequence numbers in each original message
Ambiguous process names. The solution for this problem to use naming conventions
Authentication
Performance, especially if sender and receiver processes are on the same machine
26