You are on page 1of 43

Process Management (Unit 3)

Introduction
A Program does nothing unless its instructions are executed by a CPU. A program in
execution is called a process. In order to accomplish its task, process needs the computer
resources.

There may exist more than one process in the system which may require the same resource
at the same time. Therefore, the operating system has to manage all the processes and the
resources in a convenient and efficient way.

Some resources may need to be executed by one process at one time to maintain the
consistency otherwise the system can become inconsistent and deadlock may occur.

The operating system is responsible for the following activities in connection with Process
Management

1. Scheduling processes and threads on the CPUs.


2. Creating and deleting both user and system processes.
3. Suspending and resuming processes.
4. Providing mechanisms for process synchronization.
5. Providing mechanisms for process communication.
Process memory is divided into four sections for efficient working :

 The Text section is made up of the compiled program code, read in from non-
volatile storage when the program is launched.
 The Data section is made up the global and static variables, allocated and
initialized prior to executing the main.
 The Heap is used for the dynamic memory allocation, and is managed via calls
to new, delete, malloc, free, etc.
 The Stack is used for local variables. Space on the stack is reserved for local
variables when they are declared.

Process States
 New (Create) – In this step, the process is about to be created but not yet created,
it is the program which is present in secondary memory that will be picked up by
OS to create the process.
 Ready – New -> Ready to run. After the creation of a process, the process enters
the ready state i.e. the process is loaded into the main memory. The process here
is ready to run and is waiting to get the CPU time for its execution. Processes that
are ready for execution by the CPU are maintained in a queue for ready
processes.
 Run – The process is chosen by CPU for execution and the instructions within the
process are executed by any one of the available CPU cores.
 Blocked or wait – Whenever the process requests access to I/O or needs input
from the user or needs access to a critical region (the lock for which is already
acquired) it enters the blocked or wait state. The process continues to wait in the
main memory and does not require CPU. Once the I/O operation is completed the
process goes to the ready state.
 Terminated or completed – Process is killed as well as PCB is deleted.
 Suspend ready – Process that was initially in the ready state but were swapped
out of main memory and placed onto external storage by scheduler are said to be
in suspend ready state. The process will transition back to ready state whenever
the process is again brought onto the main memory.
 Suspend wait or suspend blocked – Similar to suspend ready but uses the
process which was performing I/O operation and lack of main memory caused
them to move to secondary memory.
When work is finished it may go to suspend ready.
Process Control Block (PCB)
There is a Process Control Block for each process, enclosing all the information about
the process. It is a data structure, which contains the following:

 Process State: It can be running, waiting etc.

 Process ID and the parent process ID.

 CPU registers and Program Counter. Program Counter holds the address of the next

instruction to be executed for that process.

 CPU Scheduling information: Such as priority information and pointers to scheduling

queues.

 Memory Management information: For example, page tables or segment tables.

 Accounting information: The User and kernel CPU time consumed, account numbers,

limits, etc.

 I/O Status information: Devices allocated, open file tables, etc.


What is Process Scheduling?
The act of determining which process is in the ready state, and should be moved to
the running state is known as Process Scheduling.
The prime aim of the process scheduling system is to keep the CPU busy all the time
and to deliver minimum response time for all programs. For achieving this, the
scheduler must apply appropriate rules for swapping processes IN and OUT of CPU.
Scheduling fell into one of the two general categories:
1. Preemptive Scheduling:
Preemptive scheduling is used when a process switches from running state to
ready state or from waiting state to ready state. The resources (mainly CPU
cycles) are allocated to the process for the limited amount of time and then is
taken away, and the process is again placed back in the ready queue if that
process still has CPU burst time remaining. That process stays in ready queue till
it gets next chance to execute.
2. Non-Preemptive Scheduling:
Non-preemptive Scheduling is used when a process terminates, or a process
switches from running to waiting state. In this scheduling, once the resources
(CPU cycles) is allocated to a process, the process holds the CPU till it gets
terminated or it reaches a waiting state. In case of non-preemptive scheduling
does not interrupt a process running CPU in middle of the execution. Instead, it
waits till the process complete its CPU burst time and then it can allocate the
CPU to another process.
Process Queues
The Operating system manages various types of queues for each of the process states. The
PCB related to the process is also stored in the queue of the same state. If the Process is
moved from one state to another state then its PCB is also unlinked from the corresponding
queue and added to the other state queue in which the transition is made.

There are the following queues maintained by the Operating system.

1. Job Queue
In starting, all the processes get stored in the job queue. It is maintained in the secondary
memory. The long term scheduler (Job scheduler) picks some of the jobs and put them in
the primary memory.

2. Ready Queue
Ready queue is maintained in primary memory. The short term scheduler picks the job from
the ready queue and dispatch to the CPU for the execution.

3. Waiting Queue
When the process needs some IO operation in order to complete its execution, OS changes
the state of the process from running to waiting. The context (PCB) associated with the
process gets stored on the waiting queue which will be used by the Processor when the
process finishes the IO.
Process Schedulers
There are three types of schedulers available:

1. Long Term Scheduler


2. Short Term Scheduler
3. Medium Term Scheduler

1. Long term scheduler


Long term scheduler is also known as job scheduler. It chooses the processes from the pool
(secondary memory) and keeps them in the ready queue maintained in the primary
memory.

Long Term scheduler mainly controls the degree of Multiprogramming. The purpose of long
term scheduler is to choose a perfect mix of IO bound and CPU bound processes among the
jobs present in the pool.

If the job scheduler chooses more IO bound processes then all of the jobs may reside in the
blocked state all the time and the CPU will remain idle most of the time. This will reduce the
degree of Multiprogramming. Therefore, the Job of long term scheduler is very critical and
may affect the system for a very long time.

2. Short term scheduler


Short term scheduler is also known as CPU scheduler. It selects one of the Jobs from the
ready queue and dispatch to the CPU for the execution.

A scheduling algorithm is used to select which job is going to be dispatched for the
execution. The Job of the short term scheduler can be very critical in the sense that if it
selects job whose CPU burst time is very high then all the jobs after that, will have to wait
in the ready queue for a very long time.

This problem is called starvation which may arise if the short term scheduler makes some
mistakes while selecting the job.

3. Medium term scheduler


Medium term scheduler takes care of the swapped out processes.If the running state
processes needs some IO time for the completion then there is a need to change its state
from running to waiting.

Medium term scheduler is used for this purpose. It removes the process from the running
state to make room for the other processes. Such processes are the swapped out processes
and this procedure is called swapping. The medium term scheduler is responsible for
suspending and resuming the processes.

It reduces the degree of multiprogramming. The swapping is necessary to have a perfect


mix of processes in the ready queue.

Addition of Medium-term scheduling to the queuing diagram.

Comparison among Scheduler


S.N. Long-Term Scheduler Short-Term Scheduler Medium-Term Scheduler

1 It is a job scheduler It is a CPU scheduler It is a process swapping


scheduler.

2 Speed is lesser than short Speed is fastest among Speed is in between both short
term scheduler other two and long term scheduler.

3 It controls the degree of It provides lesser control It reduces the degree of


multiprogramming over degree of multiprogramming.
multiprogramming

4 It is almost absent or minimal It is also minimal in time It is a part of Time sharing


in time sharing system sharing system systems.
5 It selects processes from It selects those processes It can re-introduce the process
pool and loads them into which are ready to into memory and execution
memory for execution execute can be continued.

Context Switch
A context switch is the mechanism to store and restore the state or context of a CPU in
Process Control block so that a process execution can be resumed from the same
point at a later time. Using this technique, a context switcher enables multiple
processes to share a single CPU. Context switching is an essential part of a
multitasking operating system features.
When the scheduler switches the CPU from executing one process to execute another,
the state from the current running process is stored into the process control block. After
this, the state for the process to run next is loaded from its own PCB and used to set
the PC, registers, etc. At that point, the second process can start executing.
Context switches are computationally intensive since register and memory state must
be saved and restored. To avoid the amount of context switching time, some hardware
systems employ two or more sets of processor registers. When the process is
switched, the following information is stored for later use.

 Program Counter
 Scheduling information
 Base and limit register value
 Currently used register
 Changed State
 I/O State information
 Accounting information

Different Operations on Processes


There are many operations that can be performed on processes. Some of these are
process creation, process preemption, process blocking, and process termination.
These are given in detail as follows −

Process Creation
Processes need to be created in the system for different operations. This can be done
by the following events −

 User request for process creation


 System initialization
 Execution of a process creation system call by a running process
 Batch job initialization
A process may be created by another process using fork(). The creating process is
called the parent process and the created process is the child process. A child process
can have only one parent but a parent process may have many children. Both the
parent and child processes have the same memory image, open files, and environment
strings. However, they have distinct address spaces.
A diagram that demonstrates process creation using fork() is as follows −

Process Preemption
An interrupt mechanism is used in preemption that suspends the process executing
currently and the next process to execute is determined by the short-term scheduler.
Preemption makes sure that all processes get some CPU time for execution.
A diagram that demonstrates process preemption is as follows −
Process Blocking
The process is blocked if it is waiting for some event to occur. This event may be I/O as
the I/O events are executed in the main memory and don't require the processor. After
the event is complete, the process again goes to the ready state.
A diagram that demonstrates process blocking is as follows −
Process Termination
After the process has completed the execution of its last instruction, it is terminated. The
resources held by a process are released after it is terminated.
A child process can be terminated by its parent process if its task is no longer relevant.
The child process sends its status information to the parent process before it
terminates. Also, when a parent process is terminated, its child processes are
terminated as well as the child processes cannot run if the parent processes are
terminated.

Inter Process Communication (IPC)


A process can be of two types:
 Independent process.
 Co-operating process.
An independent process is not affected by the execution of other processes while a co-
operating process can be affected by other executing processes. Though one can think
that those processes, which are running independently, will execute very efficiently, in
reality, there are many situations when co-operative nature can be utilized for increasing
computational speed, convenience and modularity. Inter process communication (IPC)
is a mechanism which allows processes to communicate with each other and
synchronize their actions. The communication between these processes can be seen as
a method of co-operation between them. Processes can communicate with each other
through both:
1. Shared Memory
2. Message passing
The Figure 1 below shows a basic structure of communication between processes via
the shared memory method and via the message passing method.
An operating system can implement both method of communication. First, we will discuss the
shared memory methods of communication and then message passing. Communication
between processes using shared memory requires processes to share some variable and it
completely depends on how programmer will implement it. One way of communication using
shared memory can be imagined like this: Suppose process1 and process2 are executing
simultaneously and they share some resources or use some information from another process.
Process1 generate information about certain computations or resources being used and keeps
it as a record in shared memory. When process2 needs to use the shared information, it will
check in the record stored in shared memory and take note of the information generated by
process1 and act accordingly. Processes can use shared memory for extracting information as
a record from another process as well as for delivering any specific information to other
processes.
Let’s discuss an example of communication between processes using shared memory method.

i) Shared Memory Method


Ex: Producer-Consumer problem
There are two processes: Producer and Consumer. Producer produces some item and
Consumer consumes that item. The two processes share a common space or memory
location known as a buffer where the item produced by Producer is stored and from
which the Consumer consumes the item, if needed. There are two versions of this
problem: the first one is known as unbounded buffer problem in which Producer can
keep on producing items and there is no limit on the size of the buffer, the second one is
known as the bounded buffer problem in which Producer can produce up to a certain
number of items before it starts waiting for Consumer to consume it. We will discuss the
bounded buffer problem. First, the Producer and the Consumer will share some
common memory, then producer will start producing items. If the total produced item is
equal to the size of buffer, producer will wait to get it consumed by the Consumer.
Similarly, the consumer will first check for the availability of the item. If no item is
available, Consumer will wait for Producer to produce it. If there are items available,
Consumer will consume it.
ii) Messaging Passing Method
Now, we will start our discussion of the communication between processes via message
passing. In this method, processes communicate with each other without using any kind
of shared memory. If two processes p1 and p2 want to communicate with each other,
they proceed as follows:
 Establish a communication link (if a link already exists, no need to establish
it again.)
 Start exchanging messages using basic primitives.
We need at least two primitives:
– send(message, destination) or send(message)
– receive(message, host) or receive(message)
The message size can be of fixed size or of variable size. If it is of fixed size, it is easy for an OS
designer but complicated for a programmer and if it is of variable size then it is easy for a
programmer but complicated for the OS designer. A standard message can have two
parts: header and body.
The header part is used for storing message type, destination id, source id, message length,
and control information. The control information contains information like what to do if runs out
of buffer space, sequence number, priority. Generally, message is sent using FIFO style.

Message Passing through Communication Link

1. Direct and Indirect Communication link Naming


2. Synchronous and Asynchronous Communication Link Synchronization
3. Automatic and Explicit Buffering Buffering

Direct and Indirect Communication link


Now, We will start our discussion about the methods of implementing communication
link. While implementing the link, there are some questions which need to be kept in
mind like:
1. How are links established?
2. Can a link be associated with more than two processes?
3. How many links can there be between every pair of communicating
processes?
4. What is the capacity of a link? Is the size of a message that the link can
accommodate fixed or variable?
5. Is a link unidirectional or bi-directional?
In Direct message passing, The process which want to communicate must explicitly
name the recipient or sender of communication.
e.g. send(p1, message) means send the message to p1.
similarly, receive(p2, message) means receive the message from p2.
In this method of communication, the communication link gets established
automatically, which can be either unidirectional or bidirectional, but one link can be
used between one pair of the sender and receiver and one pair of sender and receiver
should not possess more than one pair of links. Symmetry and asymmetry between
sending and receiving can also be implemented i.e. either both processes will name
each other for sending and receiving the messages or only the sender will name
receiver for sending the message and there is no need for receiver for naming the
sender for receiving the message. The problem with this method of communication is
that if the name of one process changes, this method will not work.

In Indirect message passing, processes use mailboxes (also referred to as ports) for
sending and receiving messages. Each mailbox has a unique id and processes can
communicate only if they share a mailbox. Link established only if processes share a
common mailbox and a single link can be associated with many processes. Each pair of
processes can share several communication links and these links may be unidirectional
or bi-directional. Suppose two process want to communicate though Indirect message
passing, the required operations are: create a mail box, use this mail box for sending
and receiving messages, then destroy the mail box. The standard primitives used
are: send(A, message) which means send the message to mailbox A. The primitive for
the receiving the message also works in the same way e.g. received (A, message).
There is a problem in this mailbox implementation. Suppose there are more than two
processes sharing the same mailbox and suppose the process p1 sends a message to
the mailbox, which process will be the receiver? This can be solved by either enforcing
that only two processes can share a single mailbox or enforcing that only one process is
allowed to execute the receive at a given time or select any process randomly and notify
the sender about the receiver. A mailbox can be made private to a single
sender/receiver pair and can also be shared between multiple sender/receiver pairs.
Port is an implementation of such mailbox which can have multiple sender and single
receiver. It is used in client/server applications (in this case the server is the receiver).
The port is owned by the receiving process and created by OS on the request of the
receiver process and can be destroyed either on request of the same receiver process
or when the receiver terminates itself. Enforcing that only one process is allowed to
execute the receive can be done using the concept of mutual exclusion. Mutex
mailbox is create which is shared by n process. Sender is non-blocking and sends the
message. The first process which executes the receive will enter in the critical section
and all other processes will be blocking and will wait.

Direct Communication links are implemented when the processes uses a specific
process identifier for the communication, but it is hard to identify the sender ahead of
time.
For example: the print server.

In-direct Communication is done via a shared mailbox (port), which consists of a


queue of messages. The sender keeps the message in mailbox and the receiver picks
them up.

Message Passing through Exchanging the Messages.


Synchronous and Asynchronous Message Passing:
A process that is blocked is one that is waiting for some event, such as a resource
becoming available or the completion of an I/O operation. IPC is possible between the
processes on same computer as well as on the processes running on different
computer i.e. in networked/distributed system. In both cases, the process may or may
not be blocked while sending a message or attempting to receive a message so
message passing may be blocking or non-blocking. Blocking is
considered synchronous and blocking send means the sender will be blocked until
the message is received by receiver. Similarly, blocking receive has the receiver block
until a message is available. Non-blocking is considered asynchronous and Non-
blocking send has the sender sends the message and continue. Similarly, Non-blocking
receive has the receiver receive a valid message or null. After a careful analysis, we
can come to a conclusion that for a sender it is more natural to be non-blocking after
message passing as there may be a need to send the message to different processes.
However, the sender expects acknowledgement from the receiver in case the send fails.
Similarly, it is more natural for a receiver to be blocking after issuing the receive as the
information from the received message may be used for further execution. At the same
time, if the message sends keep on failing, the receiver will have to wait indefinitely.
That is why we also consider the other possibility of message passing. There are
basically three preferred combinations:
 Blocking send and blocking receive
 Non-blocking send and Non-blocking receive
 Non-blocking send and Blocking receive (Mostly used)

Automatic and Explicit Buffering

A link has some capacity that determines the number of messages that can reside in it
temporarily for which every link has a queue associated with it which can be of zero
capacity, bounded capacity, or unbounded capacity. In zero capacity, the sender waits
until the receiver informs the sender that it has received the message. In non-zero
capacity cases, a process does not know whether a message has been received or not
after the send operation. For this, the sender must communicate with the receiver
explicitly. Implementation of the link depends on the situation, it can be either a direct
communication link or an in-directed communication link.

Examples of IPC systems


1. Posix : uses shared memory method.
2. Mach: uses message passing
3. Windows XP: uses message passing using local procedural calls
Difference between Shared Memory Model and Message Passing Model in IPC :
S.NO SHARED MEMORY MODEL MESSAGE PASSING MODEL

Shared memory region is used for Message passing facility is used

1. communication. for communication.

It is used for communication between

processes on a single processor or

multiprocessor systems where the It is typically used in a distributed

communicating processes reside on the environment where

same machine as the communicating communicating processes reside

processes share a common address on remote machines connected

2. space. through a network.

No such code required here as the

message passing facility provides

The code for reading and writing the mechanism for communication

data from the shared memory should be and synchronization of actions

written explicitly by the Application performed by the communicating

3. programmer. processes.

4. It provides maximum speed of It is time consuming as message

computation as communication is done passing is implemented through

through shared memory so system calls kernel intervention (system calls).

are made only to establish the shared


S.NO SHARED MEMORY MODEL MESSAGE PASSING MODEL

memory.

Here the processes need to ensure that It is useful for sharing small

they are not writing to the same location amounts of data as conflicts need

5. simultaneously. not to be resolved.

Relatively slower communication

6. Faster communication strategy. strategy

Process Synchronization
Introduction
When two or more process cooperates with each other, their order of execution must be
preserved otherwise there can be conflicts in their execution and inappropriate outputs can
be produced.

A cooperative process is the one which can affect the execution of other process or can be
affected by the execution of other process. Such processes need to be synchronized so that
their order of execution can be guaranteed.

The procedure involved in preserving the appropriate order of execution of cooperative


processes is known as Process Synchronization. There are various synchronization
mechanisms that are used to synchronize the processes.

int Shared=5;
P1 P2
int X=Shared; int Y=Shared;
X++; Y--;
Sleep (1); Sleep (1);
Shared=X; Shared=Y;

Race Condition
A Race Condition typically occurs when two or more processes try to read, write and
possibly make the decisions based on the memory that they are accessing concurrently.

Critical Section
The regions of a program that try to access shared resources and may cause race conditions
are called critical section. To avoid race condition among the processes, we need to assure
that only one process at a time can execute within the critical section.

Process P1 Process P2

Non-Critical Non-Critical
Section Section

Critical Critical
Section(Shared Section(Shared
The Critical Section Problem
Code) Code)

Critical Section is the part of a program which tries to access shared resources. That
resource may be any resource in a computer like a memory location, Data structure, CPU or
any IO device.

The critical section cannot be executed by more than one process at the same time;
operating system faces the difficulties in allowing and disallowing the processes from
entering the critical section.

The critical section problem is used to design a set of protocols which can ensure that the
Race condition among the processes will never arise.

In order to synchronize the cooperative processes, our main task is to solve the critical
section problem. We need to provide a solution in such a way that the following conditions
can be satisfied.
Requirements of Synchronization
mechanisms
Primary

1. Mutual Exclusion

Our solution must provide mutual exclusion. By Mutual Exclusion, we mean that if
one process is executing inside critical section then the other process must not enter
in the critical section.
2. Progress

Progress means that if one process doesn't need to execute into critical section then
it should not stop other processes to get into the critical section.
Secondary
1. Bounded Waiting

We should be able to predict the waiting time for every process to get into the critical
section. The process must not be endlessly waiting for getting into the critical
section.

2. Architectural Neutrality

Our mechanism must be architectural natural. It means that if our solution is


working fine on one architecture then it should also run on the other ones as well.
Solutions To The Critical Section
In Process Synchronization, critical section plays the main role so that the problem
must be solved.

Here are some widely used methods to solve the critical section problem.

Peterson Solution
Peterson's solution is widely used solution to critical section problems. This
algorithm was developed by a computer scientist Peterson that's why it is named
as a Peterson's solution.

In this solution, when a process is executing in a critical state, then the other
process only executes the rest of the code, and the opposite can happen. This
method also helps to make sure that only a single process runs in the critical
section at a specific time.

Example
PROCESS Pi
FLAG[i] = true
while( (turn != i) AND (CS is !free) ){ wait;
}
CRITICAL SECTION FLAG[i] = false
turn = j; //choose another process to go to CS

 Assume there are N processes (P1, P2, ... PN) and every process at some
point of time requires to enter the Critical Section
 A FLAG[] array of size N is maintained which is by default false. So, whenever
a process requires to enter the critical section, it has to set its flag as true.
For example, If Pi wants to enter it will set FLAG[i]=TRUE.
 Another variable called TURN indicates the process number which is
currently waiting to enter into the CS.
 The process which enters into the critical section while exiting would change
the TURN to another number from the list of ready processes.
 Example: turn is 2 then P2 enters the Critical section and while exiting turn=3
and therefore P3 breaks out of wait loop.
Synchronization Hardware
Some times the problems of the Critical Section are also resolved by hardware.
Some operating system offers a lock functionality where a Process acquires a lock
when entering the Critical section and releases the lock after leaving it.

So when another process is trying to enter the critical section, it will not be able to
enter as it is locked. It can only do so if it is free by acquiring the lock itself.

Mutex Locks
Synchronization hardware not simple method to implement for everyone, so strict
software method known as Mutex Locks was also introduced.

In this approach, in the entry section of code, a LOCK is obtained over the critical
resources used inside the critical section. In the exit section that lock is released.

Semaphore Solution
Semaphore is simply a variable that is non-negative and shared between threads. It
is another algorithm or solution to the critical section problem. It is a signaling
mechanism and a thread that is waiting on a semaphore, which can be signaled by
another thread.

It uses two atomic operations, 1)wait, and 2) signal for the process
synchronization.

The definitions of wait and signal are as follows −

 Wait
The wait operation decrements the value of its argument S, if it is positive. If S is
negative or zero, then no operation is performed.

wait(S)

while (S<=0); //S=1;

S--;//S=0;
}

 Signal
The signal operation increments the value of its argument S.

signal(S)

S++;//S=1;

Types of Semaphores
There are two main types of semaphores i.e. counting semaphores and binary
semaphores. Details about these are given as follows −

 Counting Semaphores
These are integer value semaphores and have an unrestricted value domain.
These semaphores are used to coordinate the resource access, where the
semaphore count is the number of available resources. If the resources are
added, semaphore count automatically incremented and if the resources are
removed, the count is decremented.

 Binary Semaphores
The binary semaphores are like counting semaphores but their value is restricted
to 0 and 1. The wait operation only works when the semaphore is 1 and the
signal operation succeeds when semaphore is 0. It is sometimes easier to
implement binary semaphores than counting semaphores.

Advantages of Semaphores
Some of the advantages of semaphores are as follows −

 Semaphores allow only one process into the critical section. They follow the mutual
exclusion principle strictly and are much more efficient than some other methods of
synchronization.
 There is no resource wastage because of busy waiting in semaphores as processor time
is not wasted unnecessarily to check if a condition is fulfilled to allow a process to
access the critical section.
 Semaphores are implemented in the machine independent code of the microkernel. So
they are machine independent.
Disadvantages of Semaphores
Some of the disadvantages of semaphores are as follows −
 Semaphores are complicated so the wait and signal operations must be implemented in
the correct order to prevent deadlocks.
 Semaphores are impractical for last scale use as their use leads to loss of modularity.
This happens because the wait and signal operations prevent the creation of a
structured layout for the system.
 Semaphores may lead to a priority inversion where low priority processes may access
the critical section first and high priority processes later.

Classical Problems of
Synchronization
Below are some of the classical problem depicting flaws of process synchronization in
systems where cooperating processes are present.
We will discuss the following three problems:

1. Bounded Buffer (Producer-Consumer) Problem

2. Dining Philosophers Problem

3. The Readers Writers Problem

Bounded Buffer Problem


 This problem is generalized in terms of the Producer Consumer problem, where

a finite buffer pool is used to exchange messages between producer and consumer

processes.

Because the buffer pool has a maximum size, this problem is often called
the Bounded buffer problem.

 Solution to this problem is, creating two counting semaphores "full" and "empty" to keep

track of the current number of full and empty buffers respectively.


Dining Philosophers Problem
 The dining philosopher's problem involves the allocation of limited resources to a group

of processes in a deadlock-free and starvation-free manner.

 There are five philosophers sitting around a table, in which there are five

chopsticks/forks kept beside them and a bowl of rice in the centre, When a philosopher

wants to eat, he uses two chopsticks - one from their left and one from their right. When

a philosopher wants to think, he keeps down both chopsticks at their original place.

The Readers Writers Problem


 In this problem there are some processes(called readers) that only read the shared

data, and never change it, and there are other processes(called writers) who may

change the data in addition to reading, or instead of reading it.

 There are various type of readers-writers problem, most centred on relative priorities of

readers and writers.

Bounded Buffer Problem


Bounded buffer problem, which is also called producer consumer problem, is one of
the classic problems of synchronization. Let's start by understanding the problem here,
before moving on to the solution and program code.

What is the Problem Statement?


There is a buffer of n slots and each slot is capable of storing one unit of data. There
are two processes running, namely, producer and consumer, which are operating on
the buffer.
Bounded Buffer Problem

A producer tries to insert data into an empty slot of the buffer. A consumer tries to
remove data from a filled slot in the buffer. As you might have guessed by now, those
two processes won't produce the expected output if they are being executed
concurrently.
There needs to be a way to make the producer and consumer work in an independent
manner.

Here's a Solution
One solution of this problem is to use semaphores. The semaphores which will be used
here are:

 s, a binary semaphore which is used to acquire and release the lock.

 empty, a counting semaphore whose initial value is the number of slots in the buffer,

since, initially all slots are empty.


 full, a counting semaphore whose initial value is 0.

At any instant, the current value of empty represents the number of empty slots in the
buffer and full represents the number of occupied slots in the buffer.
The Producer Operation
The pseudocode of the producer function looks like this:
do

// wait until empty > 0 and then decrement 'empty';empty=2;

wait(empty); //empty=1;

// acquire lock

wait(s);

/* perform the insert operation in a slot */

// release lock

signal(s);

// increment 'full'

signal(full);

while(TRUE)

 Looking at the above code for a producer, we can see that a producer first waits until

there is atleast one empty slot.

 Then it decrements the empty semaphore because, there will now be one less empty

slot, since the producer is going to insert data in one of those slots.

 Then, it acquires lock on the buffer, so that the consumer cannot access the buffer until

producer completes its operation.

 After performing the insert operation, the lock is released and the value of full is

incremented because the producer has just filled a slot in the buffer.
The Consumer Operation
The pseudocode for the consumer function looks like this:
do

// wait until full > 0 and then decrement 'full'

wait(full);

// acquire the lock

wait(s);

/* perform the remove operation in a slot */

// release the lock

signal(s);

// increment 'empty'

signal(empty);

while(TRUE);

 The consumer waits until there is atleast one full slot in the buffer.

 Then it decrements the full semaphore because the number of occupied slots will be

decreased by one, after the consumer completes its operation.

 After that, the consumer acquires lock on the buffer.

 Following that, the consumer completes the removal operation so that the data from one

of the full slots is removed.

 Then, the consumer releases the lock.

 Finally, the empty semaphore is incremented by 1, because the consumer has just

removed data from an occupied slot, thus making it empty.


Dining Philosophers Problem
The dining philosophers problem is another classic synchronization problem which is
used to evaluate situations where there is a need of allocating multiple resources to
multiple processes.

What is the Problem Statement?


Consider there are five philosophers sitting around a circular dining table. The dining
table has five chopsticks and a bowl of rice in the middle as shown in the below figure.

Dining Philosophers Problem


At any instant, a philosopher is either eating or thinking. When a philosopher wants to
eat, he uses two chopsticks - one from their left and one from their right. When a
philosopher wants to think, he keeps down both chopsticks at their original place.

Here's the Solution


From the problem statement, it is clear that a philosopher can think for an indefinite
amount of time. But when a philosopher starts eating, he has to stop at some point of
time. The philosopher is in an endless cycle of thinking and eating.
An array of five semaphores, stick[5], for each of the five chopsticks.
The code for each philosopher looks like:
while(TRUE)

{
1 1 1 1 1
wait(stick[i]);

/* 1 2 3 4 5

mod is used because if i=5, next

chopstick is 1 (dining table is circular)

*/

wait(stick[(i+1) % 5]);

/* eat */

signal(stick[i]);

signal(stick[(i+1) % 5]);

/* think */

When a philosopher wants to eat the rice, he will wait for the chopstick at his left and
picks up that chopstick. Then he waits for the right chopstick to be available, and then
picks it too. After eating, he puts both the chopsticks down.
But if all five philosophers are hungry simultaneously, and each of them pickup one
chopstick, then a deadlock situation occurs because they will be waiting for another
chopstick forever. The possible solutions for this are:

 A philosopher must be allowed to pick up the chopsticks only if both the left and right

chopsticks are available.

 Allow only four philosophers to sit at the table. That way, if all the four philosophers pick

up four chopsticks, there will be one chopstick left on the table. So, one philosopher can

start eating and eventually, two chopsticks will be available. In this way, deadlocks can

be avoided.
What is Readers Writer
Problem?
Readers writer problem is another example of a classic synchronization problem. There
are many variants of this problem, one of which is examined below.

The Problem Statement


There is a shared resource which should be accessed by multiple processes. There are
two types of processes in this context. They are reader and writer. Any number
of readers can read from the shared resource simultaneously, but only one writer can
write to the shared resource. When a writer is writing data to the resource, no other
process can access the resource. A writer cannot write to the resource if there are non
zero number of readers accessing the resource at that time.

The Solution
From the above problem statement, it is evident that readers have higher priority than
writer. If a writer wants to write to the resource, it must wait until there are no readers
currently accessing that resource.
Here, we use one mutex m and a semaphore w. An integer variable read_count is
used to maintain the number of readers currently accessing the resource. The
variable read_count is initialized to 0. A value of 1 is given initially to m and w.
Instead of having the process to acquire lock on the shared resource, we use the
mutex m to make the process to acquire and release lock whenever it is updating
the read_count variable.
The code for the writer process looks like this:
while(TRUE)

wait(w);

/* perform the write operation */

signal(w);

}
And, the code for the reader process looks like this:
while(TRUE)

//acquire lock

wait(m);

read_count++;

if(read_count == 1)

wait(w);

//release lock

signal(m);

/* perform the reading operation */

// acquire lock

wait(m);

read_count--;

if(read_count == 0)

signal(w);

// release lock

signal(m);

Here is the Code uncoded(explained)

 As seen above in the code for the writer, the writer just waits on the w semaphore until it

gets a chance to write to the resource.


 After performing the write operation, it increments w so that the next writer can access

the resource.

 On the other hand, in the code for the reader, the lock is acquired whenever

the read_count is updated by a process.

 When a reader wants to access the resource, first it increments the read_count value,

then accesses the resource and then decrements the read_count value.

 The semaphore w is used by the first reader which enters the critical section and the last

reader which exits the critical section.

 The reason for this is, when the first readers enters the critical section, the writer is

blocked from the resource. Only new readers can access the resource now.

 Similarly, when the last reader exits the critical section, it signals the writer using

the w semaphore because there are zero readers now and a writer can have the chance

to access the resource.

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 with Thread switching does not need to interact
operating system. with operating system.

3 In multiple processing environments, each All threads can share same set of open
process executes the same code but has its files, child processes.
own memory and file resources.
4 If one process is blocked, then no other While one thread is blocked and waiting, a
process can execute until the first process is second thread in the same task can run.
unblocked.

5 Multiple processes without using threads use Multiple threaded processes use fewer
more resources. resources.

6 In multiple processes each process operates One thread can read, write or change
independently of the others. another thread's data.

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.

User Level Threads


In this case, the thread management kernel is not aware of the existence of threads.
The thread library contains code for creating and destroying threads, for passing
message and data between threads, for scheduling thread execution and for saving
and restoring thread contexts. The application starts with a single thread.
Advantages

 Thread switching does not require Kernel mode privileges.


 User level thread can run on any operating system.
 Scheduling can be application specific in the user level thread.
 User level threads are fast to create and manage.

Disadvantages

 In a typical operating system, most system calls are blocking.


 Multithreaded application cannot take advantage of multiprocessing.

Kernel Level Threads


In this case, thread management is done by the Kernel. There is no thread
management code in the application area. Kernel threads are supported directly by the
operating system. Any application can be programmed to be multithreaded. All of the
threads within an application are supported within a single process.
The Kernel maintains context information for the process as a whole and for individuals
threads within the process. Scheduling by the Kernel is done on a thread basis. The
Kernel performs thread creation, scheduling and management in Kernel space. Kernel
threads are generally slower to create and manage than the user threads.
Advantages

 Kernel can simultaneously schedule multiple threads from the same process on multiple
processes.
 If one thread in a process is blocked, the Kernel can schedule another thread of the
same process.
 Kernel routines themselves can be multithreaded.

Disadvantages

 Kernel threads are generally slower to create and manage than the user threads.
 Transfer of control from one thread to another within the same process requires a mode
switch to the Kernel.

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 Kernel-level threads are slower


and manage. to create and manage.

2 Implementation is by a thread library at Operating system supports


the user level. creation of Kernel threads.

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


on any operating system. the operating system.

4 Multi-threaded applications cannot take Kernel routines themselves can


advantage of multiprocessing. be multithreaded.

You might also like