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

Unit 2 (Os)

Uploaded by

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

Unit 2 (Os)

Uploaded by

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

Process scheduling

1. What is a process? Explain Process states and process scheduler.[7M] [SET-1,4


Feb/March2022,Jan2023][Remember]
The process scheduling is the activity of the process manager that handles the removal of the
running process from the CPU and the selection of another process on the basis of a particular
strategy.
Process scheduling is an essential part of a Multiprogramming operating systems. Such
operating systems allow more than one process to be loaded into the executable memory at a
time and the loaded process shares the CPU using time multiplexing.

Process Scheduling Queues:The OS maintains all PCBs in Process Scheduling Queues. The OS
maintains a separate queue for each of the process states and PCBs of all processes in the same
execution state are placed in the same queue. When the state of a process is changed, its PCB is
unlinked from its current queue and moved to its new state queue.

The Operating System maintains the following important process scheduling queues −
 Job queue − This queue keeps all the processes in the system.
 Ready queue − This queue keeps a set of all processes residing in main memory, ready
and waiting to execute. A new process is always put in this queue.
 Device queues − The processes which are blocked due to unavailability of an I/O device
constitute this queue.

The OS can use different policies to manage each queue (FIFO, Round Robin, Priority, etc.).
The OS scheduler determines how to move processes between the ready and run queues which
can only have one entry per processor core on the system; in the above diagram, it has been
merged with the CPU.

Process States :A process at any particular time will be in any one of the following states

1) New - the process is being created.


2) Ready - the process is ready for execution.

3) Running – the process is executing.

4) Waiting – the process is waiting for an event to occur.

5) Exit – the process completed its execution.

The change in the state of a process is indicated through the following diagram .If the process is
ready for execution on allocation of CPU then the process moves from new state to ready state.
When CPU is allocated to the process then the process moves from ready state to running state.
During execution of the process

1) If the process is completed then the process moves from running state to exit state.

2) If any i/o operation is requested then the process moves from running state to waiting state.

3) If the allocated time is over then the process moves from running state to ready state.

When the requested i/o operation is completed then the process moves from waiting state to ready
state.

Process Control Block (PCB)

Operating system creates a process control block for each process in the system. A process
control block contains information about the process. The information stored in a process control
block of a process is:

Process state: indicates state of the process.

CPU registers: indicates the values stored in registers.

CPU-scheduling information: indicates scheduling information like priority of process.

Memory management information: indicates the starting and ending positions or addresses of
process in RAM.

Accounting information: indicates process id, amount of CPU time required and so on.

I/O status information: indicates the list of i/o devices allocated to the process, a list of open files
and so on.
Two-State Process Model

Two-state process model refers to running and non-running states which are described below −

S.N State & Description


.

1 Running
When a new process is created, it enters into the system as in the running state.

2 Not Running
Processes that are not running are kept in queue, waiting for their turn to execute.
Each entry in the queue is a pointer to a particular process. Queue is implemented by
using linked list. Use of dispatcher is as follows. When a process is interrupted, that
process is transferred in the waiting queue. If the process has completed or aborted,
the process is discarded. In either case, the dispatcher then selects a process from the
queue to execute.

8. Explain fine Process state model and types of process schedulers used in each state.[7M] [SET-1
July2022][Knowledge]

Schedulers:

Schedulers are special system software which handle process scheduling in various ways. Their
main task is to select the jobs to be submitted into the system and to decide which process to run.
Schedulers are of three types −

 Long-Term Scheduler
 Short-Term Scheduler
 Medium-Term Scheduler

Long Term Scheduler


It is also called a job scheduler. A long-term scheduler determines which programs are admitted
to the system for processing. It selects processes from the queue and loads them into memory for
execution. Process loads into the memory for CPU scheduling.
The primary objective of the job scheduler is to provide a balanced mix of jobs, such as I/O
bound and processor bound. It also controls the degree of multiprogramming. If the degree of
multiprogramming is stable, then the average rate of process creation must be equal to the
average departure rate of processes leaving the system.
On some systems, the long-term scheduler may not be available or minimal. Time-sharing
operating systems have no long term scheduler. When a process changes the state from new to
ready, then there is use of long-term scheduler.
Short Term Scheduler
It is also called as CPU scheduler. Its main objective is to increase system performance in
accordance with the chosen set of criteria. It is the change of ready state to running state of the
process. CPU scheduler selects a process among the processes that are ready to execute and
allocates CPU to one of them.
Short-term schedulers, also known as dispatchers, make the decision of which process to execute
next. Short-term schedulers are faster than long-term schedulers.

Medium Term Scheduler

Medium-term scheduling is a part of swapping. It removes the processes from the memory. It
reduces the degree of multiprogramming. The medium-term scheduler is in-charge of handling
the swapped out-processes.
A running process may become suspended if it makes an I/O request. A suspended processes
cannot make any progress towards completion. In this condition, to remove the process from
memory and make space for other processes, the suspended process is moved to the secondary
storage. This process is called swapping, and the process is said to be swapped out or rolled out.
Swapping may be necessary to improve the process mix.
7.Explain about Long-term, Short-term and Medium-term schedulers[7M][SET- 3Jan2023][Knowledge]

Comparison among Scheduler


S.N. Long-Term Scheduler Short-Term Medium-Term
Scheduler 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
term scheduler other two short and long term
scheduler.

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


multiprogramming control over degree of multiprogramming.
multiprogramming

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


minimal in time sharing time sharing system systems.
system

5 It selects processes from It selects those It can re-introduce the


pool and loads them into processes which are process into memory and
memory for execution ready to execute execution can be
continued.

Context Switch
2.Explain about the dual mode operation in OS with a neat block diagram.[7M][SET-1
Feb/March2022][ Knowledge]

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
Operations A process is an activity of executing a program. Basically, it is a program
under execution. Every process needs certain resources to complete its task.

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.

3. Explain about Inter Process communication, in client – server systems. Explain the Shared-memory
systems model and Message passing model[7M][SET-1,2 Feb/Mar2022, Jan2023] [Knowledge](or)
4.Explain the basic concepts of process synchronization. How message passing mechanism is working
inwards communication of processes? [7M] [SET-1 July2022][Knowledge]

INTER PROCESS COMMUNICATION


Processes and communication
The processes that occur concurrently in the Operating systems can be of 2 types :
 Independent: These do not share any data with any other process.
 Cooperating: These processes share data with other processes. Clearly they can affect and get
affected themselves too by other processes.
Why need communication among processes ?
There are several reasons for the same. Some of them are :
Information sharing:
There may be a possibility that processes may need the same piece of information at the
same time for their execution. For example, Copying and Pasting.
Computation speed:
It is very important to have high speed in computation. If a task is subdivided into tasks
which are executed parallely, it enhances the speed and throughput of system.
Modularity:
Modularity means dividing the functions of operating system into separate processes
called Threads, to achieve improved throughput.
What is Inter-process communication?
Inter-process communication (IPC) helps to achieve the communication among the processes or
threads in a system.
It is useful mainly in the environment where the processes reside on different computer systems
connected via any type of network. A very simple and self explanatory example is
the chat system used in World Wide Web.
There are 2 basic models for IPC:
Shared Memory
23.Discuss about Message passing system with example.[7M][SET-4 Jan2022][Creating]
Message Passing

SHARED MEMORY MESSAGE PASSING

A region of memory is shared among the


processes. Messages are exchanged among the processes.

Faster than message-passsing systems. Useful for exchanging smaller amounts of data.

Only require to establish shared-memory Require more time consuming task of kernel
regions. intervention.

1. IPC in Shared-Memory Systems


A process creates the shared-memory region in it's own address space. Other processes
communicate by attaching the address space to their own address space.
Processes communicate by Reading and Writing data in the shared area. Operating system does
not have any control over data or location. It is solely determined by the processes.
2. IPC in Message-Passing Systems
Message passing provides a mechanism to allow processes to communicate and to synchronize
their actions without sharing the same address space.
It is very useful in case where the tasks or processes reside on different computers and are
connected by a network.
Messages can be of fixed or variable size. Methods for message passing operations:
1. Direct and Indirect communication
In Direct communication,
Each task explicitly pass the message along with passing name of process to which it is passing

send(task name, message)

receive(task name, message)

2. Synchronous and Asynchronous communication


Tasks make calls to each other for communication. Synchronous means blocking and
Asynchronous means non-blocking.
There are 4 cases:
->Blocking send: The sending process is blocked until message is received by receiver task.
->Non-Blocking send: The sending process sends the message according to it's requirement
without considering whether message is received or not at receiver end.
->Blocking receive: The receiving process is blocked until message is available.
->Non-Blocking receive: The receiving goes on accepting either the message or null information
continuously.
When there are both receiving and sending blocked, that case is called Rendezvous

Communication in Client-Server Model:


The Client-server model is a distributed application structure that partitions task or
workload between the providers of a resource or service, called servers, and service requesters
called clients. In the client-server architecture, when the client computer sends a request for data
to the server through the internet, the server accepts the requested process and deliver the data
packets requested back to the client. Clients do not share any of their resources. Examples of
Client-Server Model are Email, World Wide Web, etc.
How the Client-Server Model works ?
In this article we are going to take a dive into the Client-Server model and have a look at how
the Internet works via, web browsers. This article will help us in having a solid foundation of the
WEB and help in working with WEB technologies with ease.
Client: When we talk the word Client, it mean to talk of a person or an organization using a
particular service. Similarly in the digital world a Client is a computer (Host) i.e. capable of
receiving information or using a particular service from the service providers (Servers).
Servers: Similarly, when we talk the word Servers, It mean a person or medium that serves
something. Similarly in this digital world a Server is a remote computer which provides
information (data) or access to particular services.
So, its basically the Client requesting something and the Server serving it as long as its present
in the database.

How the browser interacts with the servers?


There are few steps to follow to interact with the servers a client.User enters the URL(Uniform
Resource Locator) of the website or file. The Browser then requests the DNS(DOMAIN NAME
SYSTEM) Server.
DNS Server lookup for the address of the WEB Server.
DNS Server responds with the IP address of the WEB Server.
Browser sends over an HTTP/HTTPS request to WEB Server’s IP (provided by DNS server).
Server sends over the necessary files of the website.
Browser then renders the files and the website is displayed. This rendering is done with the help
of DOM (Document Object Model) interpreter, CSS interpreter and JS Engine collectively
known as the JIT or (Just in Time) Compilers.

 Centralized system with all data in a single place.


 Cost efficient requires less maintenance cost and Data recovery is possible.
 The capacity of the Client and Servers can be changed separately.
Disadvantages of Client-Server model:
 Clients are prone to viruses, Trojans and worms if present in the Server or uploaded into
the Server.
 Servers are prone to Denial of Service (DOS) attacks.
 Data packets may be spoofed or modified during transmission.
 Phishing or capturing login credentials or other useful information of the user are common
and MITM (Man in the Middle) attacks are common.
Sockets
A socket is an endpoint for communication.
Two processes communicating over a network often use a pair of connected sockets as a
communication channel. Software that is designed for client-server operation may also use
sockets for communication between two processes running on the same computer - For example
the UI for a database program may communicate with the back-end database manager using
sockets. ( If the program were developed this way from the beginning, it makes it very easy to
port it from a single-computer system to a networked application. )
A socket is identified by an IP address concatenated with a port number, e.g. 200.100.50.5:80.

Figure 3.20 - Communication using sockets


Port numbers below 1024 are considered to be well-known, and are generally reserved for
common Internet services. For example, telnet servers listen to port 23, ftp servers to port 21, and
web servers to port 80.
General purpose user sockets are assigned unused ports over 1024 by the operating system in
response to system calls such as socket( ) or soctkepair( ).
Communication channels via sockets may be of one of two major forms:
Connection-oriented ( TCP, Transmission Control Protocol ) connections emulate a
telephone connection. All packets sent down the connection are guaranteed to arrive in good
condition at the other end, and to be delivered to the receiving process in the order in which they
were sent. The TCP layer of the network protocol takes steps to verify all packets sent, re-send
packets if necessary, and arrange the received packets in the proper order before delivering them
to the receiving process. There is a certain amount of overhead involved in this procedure, and if
one packet is missing or delayed, then any packets which follow will have to wait until the errant
packet is delivered before they can continue their journey.
Connectionless ( UDP, User Datagram Protocol ) emulate individual telegrams. There is
no guarantee that any particular packet will get through undamaged ( or at all ), and no guarantee
that the packets will get delivered in any particular order. There may even be duplicate packets
delivered, depending on how the intermediary connections are configured. UDP transmissions are
much faster than TCP, but applications must implement their own error checking and recovery
procedures.
 Sockets are considered a low-level communications channel, and processes may often
choose to use something at a higher level, such as those covered in the next two sections.

Remote Procedure Calls, RPC:


 The general concept of RPC is to make procedure calls similarly to calling on ordinary
local procedures, except the procedure being called lies on a remote machine.
 Implementation involves stubs on either end of the connection.
 The local process calls on the stub, much as it would call upon a local procedure.
 The RPC system packages up ( marshals ) the parameters to the procedure call, and
transmits them to the remote system.
 On the remote side, the RPC daemon accepts the parameters and calls upon the appropriate
remote procedure to perform the requested work.
 Any results to be returned are then packaged up and sent back by the RPC system to the
local system, which then unpackages them and returns the results to the local calling
procedure.
 One potential difficulty is the formatting of data on local versus remote systems. ( e.g. big-
endian versus little-endian. ) The resolution of this problem generally involves an agreed-
upon intermediary format, such as XDR ( external data representation. )
 Another issue is identifying which procedure on the remote system a particular RPC is
destined for.
 Remote procedures are identified by ports, though not the same ports as the socket ports
described earlier.
 One solution is for the calling procedure to know the port number they wish to
communicate with on the remote system. This is problematic, as the port number would be
compiled into the code, and it makes it break down if the remote system changes their port
numbers.
 More commonly a matchmaker process is employed, which acts like a telephone directory
service. The local process must first contact the matchmaker on the remote system ( at a
well-known port number ), which looks up the desired port number and returns it. The
local process can then use that information to contact the desired remote procedure. This
operation involves an extra step, but is much more flexible.
 One common example of a system based on RPC calls is a networked file system.
Messages are passed to read, write, delete, rename, or check status, as might be made for
ordinary local disk access requests.
Figure 3.23 - Execution of a remote procedure call ( RPC ).

Pipes:
 Pipes are one of the earliest and simplest channels of communications between ( UNIX )
processes.
 There are four key considerations in implementing pipes:
1. Unidirectional or Bidirectional communication?
2. Is bidirectional communication half-duplex or full-duplex?
3. Must a relationship such as parent-child exist between the processes?
4. Can pipes communicate over a network, or only on the same machine?
 The following sections examine these issues on UNIX and Windows
Ordinary Pipes
Ordinary pipes are uni-directional, with a reading end and a writing end. ( If bidirectional
communications are needed, then a second pipe is required. )
 In UNIX ordinary pipes are created with the system call "int pipe( int fd [ ] )".
o The return value is 0 on success, -1 if an error occurs.
o The int array must be allocated before the call, and the values are filled in by the
pipe system call:
fd[ 0 ] is filled in with a file descriptor for the reading end of the pipe
fd[ 1 ] is filled in with a file descriptor for the writing end of the pipe

 UNIX pipes are accessible as files, using standard read( ) and write( ) system calls.
 Ordinary pipes are only accessible within the process that created them.
 Typically a parent creates the pipe before forking off a child.
 When the child inherits open files from its parent, including the pipe file(s), a channel of
communication is established.
 Each process ( parent and child ) should first close the ends of the pipe that they are not
using. For example, if the parent is writing to the pipe and the child is reading, then the
parent should close the reading end of its pipe after the fork and the child should close the
writing end.
Figure shows an ordinary pipe in UNIX.

 Ordinary pipes in Windows are very similar


o Windows terms them anonymous pipes
o They are still limited to parent-child relationships.
o They are read from and written to as files.
o They are created with CreatePipe( ) function, which takes additional arguments.
o In Windows it is necessary to specify what resources a child inherits, such as pipes.

Named Pipes
 Named pipes support bidirectional communication, communication between non parent-
child related processes, and persistence after the process which created them exits. Multiple
processes can also share a named pipe, typically one reader and multiple writers.
 In UNIX, named pipes are termed fifos, and appear as ordinary files in the file system.
o ( Recognizable by a "p" as the first character of a long listing, e.g./dev/initctl )
o Created with mkfifo( ) and manipulated with read( ), write( ), open( ), close( ), etc.
o UNIX named pipes are bidirectional, but half-duplex, so two pipes are still typically
used for bidirectional communications.
o UNIX named pipes still require that all processes be running on the same machine.
Otherwise sockets are used.
 Windows named pipes provide richer communications.
 Full-duplex is supported.
 Processes may reside on the same or different machines
 Created and manipulated using CreateNamedPipe( ), ConnectNamedPipe( ),
ReadFile( ),and WriteFile( ).
Multithreading models
5. What are the benefits of Multithreaded programming? Discuss the different types of Multithreading
models in Operating System. [7M] [SET-2 Jan2023][Remember]
MULTITHREADED PROGRAMMING
Thread is an execution unit that consists of its own program counter, a stack, and a set of
registers where the program counter mainly keeps track of which instruction to execute next, a set
of registers mainly hold its current working variables, and a stack mainly contains the history of
execution

Threads are also known as Lightweight processes. Threads are a popular way to improve the
performance of an application through parallelism. Threads are mainly used to represent a
software approach in order to improve the performance of an operating system just by reducing
the overhead thread that is mainly equivalent to a classical process.
The CPU switches rapidly back and forth among the threads giving the illusion that the threads
are running in parallel.
As each thread has its own independent resource for process execution; thus Multiple processes
can be executed parallelly by increasing the number of threads.
It is important to note here that each thread belongs to exactly one process and outside a process
no threads exist. Each thread basically represents the flow of control separately. In the
implementation of network servers and web servers threads have been successfully used. Threads
provide a suitable foundation for the parallel execution of applications on shared-memory
multiprocessors.
The given below figure shows the working of a single-threaded and a multithreaded process:
Before moving on further let us first understand the difference between a process and a thread.

Process Thread

A Process simply means any program in Thread simply means a segment of a


execution. process.

The process consumes more resources Thread consumes fewer resources.

Thread requires comparatively less time


The process requires more time for creation.
for creation than process.

The process is a heavyweight process Thread is known as a lightweight process

The process takes more time to terminate The thread takes less time to terminate.

A thread mainly shares the data segment,


Processes have independent data and code
code segment, files, etc. with its peer
segments
threads.

The process takes more time for context The thread takes less time for context
switching. switching.

Communication between processes needs more Communication between threads needs


time as compared to thread. less time as compared to processes.

For some reason, if a process gets blocked then


In case if a user-level thread gets blocked,
the remaining processes can continue their
all of its peer threads also get blocked.
execution

Advantages of Thread
Some advantages of thread are given below:
1. Responsiveness
2. Resource sharing, hence allowing better utilization of resources.
3. Economy. Creating and managing threads becomes easier.
4. Scalability. One thread runs on one CPU. In Multithreaded processes, threads can be
distributed over a series of processors to scale.
5. Context Switching is smooth. Context switching refers to the procedure followed by the
CPU to change from one task to another.
6. Enhanced Throughput of the system. Let us take an example for this: suppose a process is
divided into multiple threads, and the function of each thread is considered as one job, then
the number of jobs completed per unit of time increases which then leads to an increase in
the throughput of the system.
Types of Thread
There are two types of threads:
1. User Threads
2. Kernel Threads
User threads are above the kernel and without kernel support. These are the threads that
application programmers use in their programs.
Kernel threads are supported within the kernel of the OS itself. All modern OSs support kernel-
level threads, allowing the kernel to perform multiple simultaneous tasks and/or to service
multiple kernel system calls simultaneously.
Let us now understand the basic difference between User level Threads and Kernel level threads:

User Level threads Kernel Level Threads

These threads are implemented by Operating


These threads are implemented by users.
systems

These threads are not recognized by These threads are recognized by operating
operating systems, systems,

In User Level threads, the Context switch In Kernel Level threads, hardware support is
requires no hardware support. needed.

These threads are mainly designed as These threads are mainly designed as
dependent threads. independent threads.

In User Level threads, if one user-level On the other hand, if one kernel thread
thread performs a blocking operation then performs a blocking operation then another
the entire process will be blocked. thread can continue the execution.

Example of User Level threads: Java Example of Kernel level threads: Window Solaris.
thread, POSIX threads.

While the Implementation of the kernel-level


Implementation of User Level thread is
thread is done by the operating system and is
done by a thread library and is easy.
complex.

This thread is generic in nature and can


This is specific to the operating system.
run on any operating system.

6.What resources are used when a Thread is created? How do they differ from those used when a Process
is created? [7M] [SET-3 Jan2023][Remember]

Multithreading Models
The user threads must be mapped to kernel threads, by one of the following strategies:
 Many to One Model
 One to One Model
 Many to Many Model
Many to One Model
 In the many to one model, many user-level threads are all mapped onto a single kernel
thread.
 Thread management is handled by the thread library in user space, which is efficient in
nature.
 In this case, if user-level thread libraries are implemented in the operating system in some
way that the system does not support them, then the Kernel threads use this many-to-one
relationship model.

One to One Model


 The one to one model creates a separate kernel thread to handle each and every user
thread.
 Most implementations of this model place a limit on how many threads can be created.
 Linux and Windows from 95 to XP implement the one-to-one model for threads.
 This model provides more concurrency than that of many to one Model.

Many to Many Model


 The many to many model multiplexes any number of user threads onto an equal or
smaller number of kernel threads, combining the best features of the one-to-one and many-
to-one models.
 Users can create any number of threads.
 Blocking the kernel system calls does not block the entire process.
 Processes can be split across multiple processors.

What are Thread Libraries?


Thread libraries provide programmers with API for the creation and management of threads.
Thread libraries may be implemented either in user space or in kernel space. The user space
involves API functions implemented solely within the user space, with no kernel support. The
kernel space involves system calls and requires a kernel with thread library support.
Three types of Thread
1. POSIX Pitheads may be provided as either a user or kernel library, as an extension to the
POSIX standard.
2. Win32 threads are provided as a kernel-level library on Windows systems.
3. Java threads: Since Java generally runs on a Java Virtual Machine, the implementation of
threads is based upon whatever OS and hardware the JVM is running on, i.e. either
Pitheads or Win32 threads depending on the system.
POSIX Pitheads:
 pThreads are available on Solaris, Linux, Mac OSX, Tru64, and via public domain
shareware for Windows.
 Global variables are shared amongst all threads.
 One thread can wait for the others to rejoin before continuing.
 pThreads begin execution in a specified function, in this example the runner( ) function
Java threads:
 Threads are the fundamental model of program execution in a Java program.
 Java language and its API provide a rich set of features for the creationand management of
threads.
 All Java programs comprise at least a single thread, even a simple Java program consisting
of only a main() method runs as a single thread in the JVM.
 JVM is running on top of a host OS, the Java thread API is typically implemented using a
thread library available on the host system.
 There are two techniques for creating threads in a Java program.
⚫ One approach is to create a new class that is derived from the Thread class
and to override its run() method.
⚫ An alternative—and more commonly used— technique is to define a class
that implements the Runnable interface
Win32 threads:
The technique for creating threads using the Win32 thread library is similar to the Pthreads
technique in several ways.
• we must include the windows.h header file when using the Win32 API.
• Threads are created in the Win32 API using the CreateThread()function and—just as in
Pthreads—a set of attributes for the thread is passed to this function.
Multithreading Issues
Below we have mentioned a few issues related to multithreading. Well, it's an old saying, All
good things, come at a price.
⚫ The fork() and exec() system call
⚫ Signal handling
⚫ Thread cancelation
⚫ Thread local storage
⚫ Scheduler activation
The fork() and exec() system call
Fork system call is used for creating a new process, which is called child process, which runs
concurrently with the process that makes the fork() call.
The exec system call is used to execute a file which is residing in an active process. When exec is
called the previous executable file is replaced and new file is executed.
Signal Handling
⚫ Whenever a multithreaded process receives a signal then to what thread
should that signal be conveyed? There are following option for signal
distribution:
⚫ 1. Signal deliver to the thread to which the signal applies.
⚫ 2. Signal deliver to each and every thread in the process.
⚫ 3. Signal deliver to some of the threads in the process.
Thread Cancellation
⚫ Threads that are no-longer required can be cancelled.
⚫ Asynchronies Cancellation It means cancellation of thread immediately.
Deferred Cancellation that indicating the thread should cancel itself when it is feasible
Thread Local Storage
⚫ The benefit of using threads in the first place is that Most data is shared
among the threads.
which provide support for thread specific which is called as thread local storage
Scheduler Activation
⚫ Threads provides a virtual processor as an interface b/w user and kernel thread
specifically for two tier model.
⚫ The virtual processor is called as low weight process (LWP).
The O.S is used to schedule on to the real system with the help of low weight process
Multithreading Model:
Multithreading allows the application to divide its task into individual threads. In multi-threads,
the same process or task can be done by the number of threads, or we can say that there is more
than one thread to perform the task in multithreading. With the use of multithreading,
multitasking can be achieved.

The main drawback of single threading systems is that only one task can be performed at a time,
so to overcome the drawback of this single threading, there is multithreading that allows multiple
tasks to be performed.
For example:

In the above example, client1, client2, and client3 are accessing the web server without any
waiting. In multithreading, several tasks can run at the same time.
In an operating system, threads are divided into the user-level thread and the Kernel-level thread.
User-level threads handled independent form above the kernel and thereby managed without any
kernel support. On the opposite hand, the operating system directly manages the kernel-level
threads. Nevertheless, there must be a form of relationship between user-level and kernel-level
threads.
1. 15.What is thread scheduling in the context of an operating system, and how does it differ from
process scheduling? Provide a brief explanation of the terms 'thread priority' and 'context
switching' in the context of thread scheduling. [7M][Remember](or) 24.What is a barrier and
why is it important for synchronization among threads or processes? [7M][Remember]
Thread Scheduling
Scheduling of threads involves two boundary scheduling,

 Scheduling of user level threads (ULT) to kernel level threads (KLT) via leightweight
process (LWP) by the application developer.
 Scheduling of kernel level threads by the system scheduler to perform different unique os
functions.
Lightweight Process (LWP) :
Light-weight process are threads in the user space that acts as an interface for the ULT to access
the physical CPU resources. Thread library schedules which thread of a process to run on which
LWP and how long. The number of LWP created by the thread library depends on the type of
application. In the case of an I/O bound application, the number of LWP depends on the number
of user-level threads. This is because when an LWP is blocked on an I/O operation, then to
invoke the other ULT the thread library needs to create and schedule another LWP. Thus, in an
I/O bound application, the number of LWP is equal to the number of the ULT. In the case of a
CPU bound application, it depends only on the application. Each LWP is attached to a separate
kernel-level thread.
In real-time, the first boundary of thread scheduling is beyond specifying the scheduling policy
and the priority. It requires two controls to be specified for the User level threads: Contention
scope, and Allocation domain. These are explained as following below.
1. Contention Scope :
The word contention here refers to the competition or fight among the User level threads to
access the kernel resources. Thus, this control defines the extent to which contention takes place.
It is defined by the application developer using the thread library. Depending upon the extent of
contention it is classified as Process Contention Scope and System Contention Scope.
1. Process Contention Scope (PCS) –
The contention takes place among threads within a same process. The thread library
schedules the high-prioritized PCS thread to access the resources via available LWPs
(priority as specified by the application developer during thread creation).
2. System Contention Scope (SCS) –
The contention takes place among all threads in the system. In this case, every SCS
thread is associated to each LWP by the thread library and are scheduled by the system
scheduler to access the kernel resources.
In LINUX and UNIX operating systems, the POSIX Pthread library provides a
function Pthread_attr_setscope to define the type of contention scope for a thread during its
creation.
int Pthread_attr_setscope(pthread_attr_t *attr, int scope)
The first parameter denotes to which thread within the process the scope is defined.
The second parameter defines the scope of contention for the thread pointed. It takes two values.
PTHREAD_SCOPE_SYSTEM
PTHREAD_SCOPE_PROCESS
If the scope value specified is not supported by the system, then the function returns ENOTSUP.
2. Allocation Domain :
The allocation domain is a set of one or more resources for which a thread is competing. In a
multicore system, there may be one or more allocation domains where each consists of one or
more cores. One ULT can be a part of one or more allocation domain. Due to this high
complexity in dealing with hardware and software architectural interfaces, this control is not
specified. But by default, the multicore system will have an interface that affects the allocation
domain of a thread.

Consider a scenario, an operating system with three process P1, P2, P3 and 10 user level threads
(T1 to T10) with a single allocation domain. 100% of CPU resources will be distributed among
all the three processes. The amount of CPU resources allocated to each process and to each thread
depends on the contention scope, scheduling policy and priority of each thread defined by the
application developer using thread library and also depends on the system scheduler. These User
level threads are of a different contention scope.

In this case, the contention for allocation domain takes place as follows,
1. Process P1:
All PCS threads T1, T2, T3 of Process P1 will compete among themselves. The PCS
threads of the same process can share one or more LWP. T1 and T2 share an LWP and T3
are allocated to a separate LWP. Between T1 and T2 allocation of kernel resources via
LWP is based on preemptive priority scheduling by the thread library. A Thread with a
high priority will preempt low priority threads. Whereas, thread T1 of process p1 cannot
preempt thread T3 of process p3 even if the priority of T1 is greater than the priority of T3.
If the priority is equal, then the allocation of ULT to available LWPs is based on the
scheduling policy of threads by the system scheduler(not by thread library, in this case).
2. Process P2:
Both SCS threads T4 and T5 of process P2 will compete with processes P1 as a whole and
with SCS threads T8, T9, T10 of process P3. The system scheduler will schedule the
kernel resources among P1, T4, T5, T8, T9, T10, and PCS threads (T6, T7) of process P3
considering each as a separate process. Here, the Thread library has no control of
scheduling the ULT to the kernel resources.
3. Process P3:
Combination of PCS and SCS threads. Consider if the system scheduler allocates 50% of
CPU resources to process P3, then 25% of resources is for process scoped threads and the
remaining 25% for system scoped threads. The PCS threads T6 and T7 will be allocated to
access the 25% resources based on the priority by the thread library. The SCS threads T8,
T9, T10 will divide the 25% resources among themselves and access the kernel resources
via separate LWP and KLT. The SCS scheduling is by the system scheduler.
Note:
For every system call to access the kernel resources, a Kernel Level thread is created and
associated to separate LWP by the system scheduler.
Number of Kernel Level Threads = Total Number of LWP
Total Number of LWP = Number of LWP for SCS + Number of LWP for PCS
Number of LWP for SCS = Number of SCS threads
Number of LWP for PCS = Depends on application developer
Here,
Number of SCS threads = 5
Number of LWP for PCS = 3
Number of SCS threads = 5
Number of LWP for SCS = 5
Total Number of LWP = 8 (=5+3)
Number of Kernel Level Threads = 8
Advantages of PCS over SCS :
 If all threads are PCS, then context switching, synchronization, scheduling everything
takes place within the userspace. This reduces system calls and achieves better
performance.
 PCS is cheaper than SCS.
 PCS threads share one or more available LWPs. For every SCS thread, a separate LWP is
associated.For every system call, a separate KLT is created.
 The number of KLT and LWPs created highly depends on the number of SCS threads
created. This increases the kernel complexity of handling scheduling and synchronization.
Thereby, results in a limitation over SCS thread creation, stating that, the number of SCS
threads to be smaller than the number of PCS threads.
 If the system has more than one allocation domain, then scheduling and synchronization of
resources becomes more tedious. Issues arise when an SCS thread is a part of more than
one allocation domain, the system has to handle n number of interfaces.
The second boundary of thread scheduling involves CPU scheduling by the system scheduler.
The scheduler considers each kernel-level thread as a separate process and provides access to the
kernel resources.
PROCESS SCHEDULING
⚫ CPU scheduling is the basis of multi programmed operating systems. By
switching the CPU among processes.
⚫ In a single-processor system, only one process can run at a time; any others
must wait until the CPU is free.
CPU-I/O Burst Cycle:

⚫ Process execution consists of a cycle of CPU execution and I/O wait.


⚫ Processes alternate between these two states. Process execution begins with a
CPU burst.That is followed by an I/O burst, which is followed by another
CPU burst, then another I/O burst, and so on.
Scheduling Criteria
The criteria include the following:
There are many different criteria to check when considering the "best" scheduling algorithm,
they are:
 CPU Utilization:To make out the best use of the CPU and not to waste any CPU cycle, the
CPU would be working most of the time(Ideally 100% of the time). Considering a real
system, CPU usage should range from 40% (lightly loaded) to 90% (heavily loaded.)
 Throughput:It is the total number of processes completed per unit of time or rather says the
total amount of work done in a unit of time. This may range from 10/second to 1/hour
depending on the specific processes.
 Turnaround Time:It is the amount of time taken to execute a particular process, i.e. The
interval from the time of submission of the process to the time of completion of the
process(Wall clock time).
 Waiting Time:The sum of the periods spent waiting in the ready queue amount of time a
process has been waiting in the ready queue to acquire get control on the CPU.
 Load Average:It is the average number of processes residing in the ready queue waiting
for their turn to get into the CPU.
 Response Time:Amount of time it takes from when a request was submitted until the first
response is produced. Remember, it is the time till the first response and not the
completion of process execution(final response).
In general CPU utilization and Throughput are maximized and other factors are reduced for
proper optimization.
Scheduling Algorithms
CPU scheduling deals with the problem of deciding which of the processes in the ready queue is
to be allocated the CPU.
There are many different CPU scheduling algorithms.
⚫ First-Come, First-Served Scheduling
⚫ Shortest-Job-First Scheduling
⚫ Priority Scheduling
⚫ Round-Robin Scheduling
⚫ Multilevel Queue Scheduling
⚫ Multilevel Feedback-Queue Scheduling

Whenever the CPU becomes idle, the operating system must select one of the Processes in the
ready queue to be executed. The selection process is carried out by the short- term scheduler (or
CPU scheduler).
The scheduler selects a process from the processes in memory that are ready to execute and
allocates the CPU to that process.
Two types of scheduking
⚫ Preemptive Scheduling removing a process from its running state.
⚫ Non Preemptive Scheduling Jobs can not be preempted unless they Complete
the job.
CPU scheduling decisions may take place under the following four circumstances:
1. When a process switches from the running state to the waiting state(for I/O request or
invocation of wait for the termination of one of the child processes).
2. When a process switches from the running state to the ready state (for example, when an
interrupt occurs).
3. When a process switches from the waiting state to the ready state(for example,
completion of I/O).
4. When a process terminates.
In circumstances 1 and 4, there is no choice in terms of scheduling. A new process(if one exists in
the ready queue) must be selected for execution. There is a choice, however in circumstances 2
and 3.
When Scheduling takes place only under circumstances 1 and 4, we say the scheduling scheme
is non-pre-emptive; otherwise, the scheduling scheme is pre-emptive.
Non-Pre-emptive Scheduling
Under non-pre-emptive scheduling, once the CPU has been allocated to a process, the process
keeps the CPU until it releases the CPU either by terminating or by switching to the waiting state.
This scheduling method is used by the Microsoft Windows 3.1 and by the Apple Macintosh
operating systems.
It is the only method that can be used on certain hardware platforms because It does not require
the special hardware(for example a timer) needed for preemptive scheduling.
In non-preemptive scheduling, it does not interrupt a process running CPU in the middle of the
execution. Instead, it waits till the process completes its CPU burst time, and then after that it can
allocate the CPU to any other process.
Some Algorithms based on non-preemptive scheduling are: Shortest Job First (SJF basically non-
preemptive) Scheduling and Priority (non- preemptive version) Scheduling, etc.

Pre-emptive Scheduling
In this type of Scheduling, the tasks are usually assigned with priorities. At times it is necessary
to run a certain task that has a higher priority before another task although it is running.
Therefore, the running task is interrupted for some time and resumed later when the priority task
has finished its execution.
Thus this type of scheduling is used mainly when a process switches either from running state to
ready state or from waiting state to ready state. The resources (that is CPU cycles) are mainly
allocated to the process for a limited amount of time and then are taken away, and after that, the
process is again placed back in the ready queue in the case if that process still has a CPU burst
time remaining. That process stays in the ready queue until it gets the next chance to execute.
Some Algorithms that are based on preemptive scheduling are Round Robin Scheduling (RR),
Shortest Remaining Time First (SRTF), Priority (preemptive version) Scheduling, etc.

Scheduling Algorithms
To decide which process to execute first and which process to execute last to achieve maximum
CPU utilization, computer scientists have defined some algorithms, they are:
There are SEVEN different types of scheduling algorithms whose name are as follows:
To understand these scheduling, first, we discuss some terms that we need in each scheduling
process.
• Arrival time is the time at which the process arrives in the ready queue for execution, and it is
given in our table when we need to calculate the average waiting time.
• Completion time is the time at which the process finishes its execution.
• Turnaround time is the difference between completion time and arrival time, i.e. turnaround
time = Completion time- arrival time
• Burst time is the time required by the process for execution of the process by CPU.
• Waiting time (W.T) is the difference between turnaround time and burst time, i.e. waiting
time= Turnaround time – Burst time
Now we will discuss the scheduling algorithms one by one.

13. Consider the following four processes, with the length of the CPU burst time given in the following:
Process Arrival Time(ms) Burst Time (ms)
P1 1 6
P2 1 5
P3 2 5
P4 2 3
Find Average Waiting Time and Turnaround time for given Process using FCFS and SJF
Algorithms [7M] [SET1 Feb/march2022][Analyze]
FIRST-COME, FIRST-SERVED SCHEDULING
By far the simplest CPU-scheduling algorithm is the first-come, first-served (FCFS) scheduling
algorithm. With this scheme, the process that requests the CPU first is allocated the CPU first.
The implementation of the FCFS policy is easily managed with a FIFO queue.

When a process enters the ready queue, its PCB is linked onto the tail of the queue. When the
CPU is free, it is allocated to the process at the head of the queue. The running process is then
removed from the queue. The code for FCFS scheduling is simple to write and understand.
The average waiting time under the FCFS policy, however, is often quite long. Consider the
following set of processes that arrive at time 0, with the length of the CPU burst given in
milliseconds:

If the processes arrive in the order Pi, Po, P3, and are served in FCFS order we get the result
shown in the following Gantt chart:

The waiting time is 0 milliseconds for process Pi, 24 milliseconds for process Pn, and 27
milliseconds for process Pj. Thus, the average waiting time is (0 + 24 + 27)/3 = 17 milliseconds.
If the processes arrive in the order Pi, P3, Pi, however, the results will be as showrn in the
following Gantt chart:

The average waiting time is now (6 + 0 + 3)/3 = 3 milliseconds. This reduction is substantial.
Thus, the average waiting time under an FCFS policy is generally not minimal and may vary
substantially if the process's CPU burst times vary greatly.
The average waiting time is now (6 + 0 + 3)/3 = 3 milliseconds. This reduction is substantial.
Thus, the average waiting time under an FCFS policy is generally not minimal and may vary
substantially if the process's CPU burst times vary greatly.
Assume we have one CPU-bound process and many I/O-bound processes. As the processes flow
around the system, the following scenario may result. The CPU-bound process will get and hold
the CPU.
During this time, all the other processes will finish their I/O and will move into the ready queue,
waiting for the CPU. While the processes wait in the ready queue, the I/O devices are idle.
Eventually, the CPU-bound process finishes its CPU burst and moves to an I/O device.
All the I/O-bound processes, which have short CPU bursts, execute quickly and move back to the
I/O queues. At this point, the CPU sits idle. The CPU-bound process will then move back to the
ready queue and be allocated the CPU.
Again, all the I/O processes end up waiting in the ready queue until the CPU-bound process is
done. There is a convoy effect as all the other processes wait for the one big process to get off the
CPU.
This effect results in lower CPU and device utilization than might be possible if the shorter
processes were allowed to go first. The FCFS scheduling algorithm is non preemptive. Once the
CPU has been allocated to a process, that process keeps the CPU until it releases the CPU, either
by terminating or by requesting I/O.
The FCFS algorithm is thus particularly troublesome for time-sharing systems, where it is
important that each user get a share of the CPU at regular intervals. It would be disastrous to
allow one process to keep the CPU for an extended period.

11.Describe the characteristics of SJF scheduling algorithm. Consider there are five jobs named P1, P2,
P3, P4 and P5. Their arrival time and burst times are given below.
process id arrival time burst time
p1 1 7
p2 3 3
p3 6 2
p4 7 10
p5 9 8
Draw a Gantt chart illustrating the execution of these jobs using SJF algorithm and also
Calculate the average waiting time and average turnaround time. [7M] [SET-3 Jan2023]
[Analyze]
SHORTEST-JOB-FIRST SCHEDULING
A different approach to CPU scheduling is the shortest-job-first (SJF) scheduling algorithm. This
algorithm associates with each process the length of the process's next CPU burst. When the CPU
is available, it is assigned to the process that has the smallest next CPU burst. If the next CPU
bursts of two processes are the same, FCFS scheduling is used to break the tie.
Note that a more appropriate term for this scheduling method would be the shortest-next-CPU-
burst algorithm, because scheduling depends on the length of the next CPU burst of a process,
rather than its total length.
We use the term SJF because most people and textbooks use this term to refer to this type of
scheduling. As an example of SJF scheduling, consider the following set of processes, with the
length of the CPU burst given in milliseconds:

Using SJF scheduling, we would schedule these processes according to the following Gantt chart:

The waiting time is 3 milliseconds for process P\, 16 milliseconds for process Pi, 9 milliseconds
for process P$, and 0 milliseconds for process P4. Thus, the average waiting time is (3 + 16 + 9 +
0)/4 - 7 milliseconds. By comparison, if we were using the FCFS scheduling scheme, the average
waiting time would be 10.25 milliseconds.
The SJF scheduling algorithm is provably optimal, in that it gives the minimum average waiting
time for a given set of processes. Moving a short process before a long one decreases the waiting
time of the short process more than it increases the waiting time of the long process.
Consequently, the average waiting time decreases. The real difficulty with the SJF algorithm is
knowing the length of the next CPU request. For long-term (job) schedtiling in a batch system,
we can use as the length the process time limit that a user specifies when he submits the job.
Thus, users are motivated to estimate the process time limit accurately, since a lower value may
mean faster response. (Too low a value will cause a time-limit-exceeded error and require
resubmission.) SJF scheduling is used frequently in long-term scheduling.
Although the SJF algorithm is optimal, it cannot be implemented at the level of short-term CPU
scheduling. There is no way to know the length of the next CPU burst. One approach is to try to
approximate SJF scheduling. We may not know the length of the next CPU burst, but we may be
able to predict its value. We expect that the next CPU burst will be similar in length to the
previous ones.
Thus, by computing an approximation of the length of the next CPU burst, we can pick the
process with the shortest predicted CPU burst. The next CPU burst is generally predicted as an
exponential average of the measured lengths of previous CPU bursts.
Let tn be the length of the Tth CPU Although the SJF algorithm is optimal, it cannot be
implemented at the level of short-term CPU scheduling. There is no way to know the length of
the next CPU burst. One approach is to try to approximate SJF scheduling.
We may not know the length of the next CPU burst, but we may be able to predict its value. We
expect that the next CPU burst will be similar in length to the previous ones. Thus, by computing
an approximation of the length of the next CPU burst, we can pick the process with the shortest
predicted CPU burst.
The next CPU burst is generally predicted as an exponential average of the measured lengths of
previous CPU bursts. Let tn be the length of the »th CPU

10.Consider the Set of 5 processes whose arrival time and burst time are given below.
Process id arrival time burst time priority
P1 0 4 2
P2 1 3 3
P3 2 1 4
P4 3 5 5
P5 4 2 5
If the CPU scheduling policy is priority non-preemptive, calculate the Average Waiting time and
Average Turnaround time. (Higher number represents higher Priority [7M] [SET-2 Jan2023]
[Analyze] (or)

12.Consider the Set of 5 processes whose arrival time and burst time are given below
process id arrival time burst time priority
p1 0 4 2
p2 1 3 3
p3 2 1 4
p4 3 5 5
p5 4 2 5
If the CPU scheduling policy is priority preemptive, calculate the average waiting time and
average turn around time. (Higher number represents higher priority. [7M] [SET-4 Jan2023]
[Analyze]
PRIORITY SCHEDULING
The SJF algorithm is a special case of the general priority scheduling algorithm. A priority is
associated with each process, and the CPU is allocated to the process with the highest priority.
Equal-priority processes are scheduled in FCFS order.

An SJF algorithm is simply a priority algorithm where the priority (p) is the inverse of the
(predicted) next CPU burst. The larger the CPU burst, the lower the priority, and vice versa. Note
that we discuss scheduling in terms of high priority and low priority. Priorities are generally
indicated by some fixed range of numbers, such as 0 to 7 or 0 to 4,095.
However, there is no general agreement on whether 0 is the highest or lowest priority. Some
systems use low numbers to represent low priority; others use low numbers for high priority. This
difference can lead to confusion. In this text, we assume that low numbers represent high priority.
As an example, consider the following set of processes, assumed to have arrived at time 0, in the
order Pi, P2, • • -, P5, with the length of the CPU burst given in milliseconds:

Using priority scheduling, we would schedule these processes according to the following Gantt
chart:

The average waiting time is 8.2 milliseconds.


Priority scheduling can be either preemptive or nonpreemptive. When a process arrives at the
ready queue, its priority is compared with the priority of the currently running process. A
preemptive priority scheduling algorithm will preempt the CPU if the priority of the newly
arrived process is higher than the priority of the currently running process. A nonpreemptive
priority scheduling algorithm will simply put the new process at the head of the ready queue.
A solution to the problem of indefinite blockage of low-priority processes is aging. Aging is a
technique of gradually increasing the priority of processes that wait in the system for a long time.
9.Write the important characteristics of Round Robin Scheduling algorithm. And demonstrate its
performance for the following workload in a system with time.quantum = 2 units
Consider the Set of 5 processes whose arrival time and burst time are given. Below
process id arrival time burst time
p1 5 5
p2 4 6
p3 3 7
p4 1 9
p5 2 2
p6 6 3
Draw a Gantt chart illustrating the execution of these jobs and calculate the Average waiting and average
turn around times[7M] [SET-1 Jan2023] [Evaluate]
ROUND-ROBIN SCHEDULING
The round-robin (RR) scheduling algorithm is designed especially for timesharing systems. It is
similar to FCFS scheduling, but preemption is added to switch between processes. A small unit of
time, called a time quantum or time slice, is defined. A time quantum is generally from 10 to 100
milliseconds. The ready queue is treated as a circular queue.

The CPU scheduler goes around the ready queue, allocating the CPU to each process for a time
interval of up to 1 time quantum. To implement RR scheduling, we keep the ready queue as a
FIFO queue of processes. New processes are added to the tail of the ready queue.
The CPU scheduler picks the first process from the ready queue, sets a timer to interrupt after 1
time quantum, and dispatches the process. One of two things will then happen. The process may
have a CPU burst of less than 1 time quantum. In this case, the process itself will release the CPU
voluntarily.
The scheduler will then proceed to the next process in the ready queue. Otherwise, if the CPU
burst of the currently running process is longer than 1 time quantum, the timer will go off and
will cause an interrupt to the operating system. A context switch will be executed, and the process
will be put at the tail of the ready queue.
The CPU scheduler will then select the next process in the ready queue. The average waiting time
under the RR policy is often long. Consider the following set of processes that arrive at time 0,
with the length of the CPU burst given in milliseconds:

If we use a time quantum of 4 milliseconds, then process Pi gets the first 4 milliseconds. Since it
requires another 20 milliseconds, it is preempted after the first time quantum, and the CPU is
given to the next process in the queue, process P2. Since process Pi does not need 4 milliseconds,
it quits before its time quantum expires. The CPU is then given to the next process, process P3.
Once each process has received 1 time quantum, the CPU is returned to process Pi for an
additional time quantum. The resulting RR schedule is

The average waiting time is 17/3 = 5.66 milliseconds. In the RR scheduling algorithm, no process
is allocated the CPU for more than 1 time quantum in a row (unless it is the only runnable
process). If a process's CPU burst exceeds 1 time quantum, that process is preempted and is put
back in the ready queue. The RR scheduling algorithm is thus preemptive.
If there are n processes in the ready queue and the time quantum is q, then each process gets 1/n
of the CPU time in chunks of at most q time units. Each process must wait no longer than (n — 1)
x q time units until its next time quantum. For example, with five processes and a time quantum
of 20 milliseconds, each process will get up to 20 milliseconds every 100 milliseconds.
The performance of the RR algorithm depends heavily on the size of the time quantum. At one
extreme, if the time quantum is extremely large, the RR policy is the same as the FCFS policy If
the time quantum is extremely small (say, 1 millisecond), the RR approach is called processor
sharing and (in theory) creates the appearance that each of n processes has its own processor
running at 1/n the speed of the real processor.
Turnaround time also depends on the size of the time quantum. In general, the average turnaround
time can be improved if most processes finish their next CPU burst in a single time quantum.
Although the time quantum should be large compared with the context switch time, it should not
be too large. If the time quantum is too large, RR scheduling degenerates to FCFS policy. A rule
of thumb is that 80 percent of the CPU bursts should be shorter than the time quantum.
Multilevel Queue Scheduling

⚫ A multilevel queue-scheduling algorithm partitions the ready queue into


several separate queues.

⚫ The processes are permanently assigned to one queue, generally based on


some property of the process, such as memory size, process priority, or
process type

⚫ .Each queue has its own scheduling algorithm

Multilevel Feedback Queue Scheduling

⚫ Multilevel feedback queue scheduling, however, allows a process to move


between queues. The idea is to separate processes with different CPU-burst
characteristics. If a process uses too much CPU time, it will be moved to a
lower-priority queue. This scheme leaves I/O-bound and interactive processes
in the higher-priority queues. Similarly, a process that waits too long in a
lower priority queue may be moved to a higher-priority queue.
14.What are the main advantages and challenges of implementing multiprocessor scheduling in an
operating system, and how does it differ from single-processor scheduling in terms of resource
allocation and performance optimization?[7M] [Remember]
Multiple-Processor Scheduling
multiprocessor scheduling focuses on designing the scheduling function for the system which
is consist of ‘more than one processor’.
With multiple processors in the system, the load sharing becomes feasible but it makes
scheduling more complex

Techniques of multiprocessor Scheduling

1. asymmetric multiprocessor scheduling

2. symmetric multiprocessor scheduling

3. Processor Affinity

4. Load Balancing

In asymmetric multiprocessor scheduling, one processor is assigned as the master processor


which handles all the decisions related to scheduling, along with I/O processing and other system
activities. It the master processor which runs the operating systems code and the other slave
processors only execute the user code.
In symmetric multiprocessor scheduling, all the processors in the system are self-scheduling.
Each processor in the system either has its own list of processes to be executed.
16.Explain about Inter Process Communication in client – server systems. [7M] [SET-1 Feb/march2022]
[Knowledge]
INTER-PROCESS COMMUNICATION:
Process Synchronization is the task of coordinating the execution of processes in a way that no
two processes can have access to the same shared data and resources.

It is specially needed in a multi-process system when multiple processes are running together, and
more than one processes try to gain access to the same shared resource or data at the same time.
This can lead to the inconsistency of shared data. So the change made by one process not
necessarily reflected when other processes accessed the same shared data. To avoid this type of
inconsistency of data, the processes need to be synchronized with each other.
How Process Synchronization Works?
For Example, process A changing the data in a memory location while another process B is trying
to read the data from the same memory location. There is a high probability that data read by the
second process will be erroneous.

Sections of a Program
Here, are four essential elements of the critical section:
 Entry Section: It is part of the process which decides the entry of a particular process.
 Critical Section: This part allows one process to enter and modify the shared variable.
 Exit Section: Exit section allows the other process that are waiting in the Entry Section, to
enter into the Critical Sections. It also checks that a process that finished its execution
should be removed through this Section.
 Remainder Section: All other parts of the Code, which is not in Critical, Entry, and Exit
Section, are known as the Remainder Section.
17.What is the Critical section problem in Operating systems? Explain it.[7M] [SET-3 Jan2023] [Remember]
What is Critical Section Problem?
A critical section is a segment of code which can be accessed by a signal process at a specific
point of time. The section consists of shared data resources that required to be accessed by other
processes.
 The entry to the critical section is handled by the wait() function, and it is represented as
P().
 The exit from a critical section is controlled by the signal() function, represented as V().
In the critical section, only a single process can be executed. Other processes, waiting to execute
their critical section, need to wait until the current process completes its execution.
Rules for Critical Section
The critical section need to must enforce all three rules:
 Mutual Exclusion: Mutual Exclusion is a special type of binary semaphore which is used
for controlling access to the shared resource. It includes a priority inheritance mechanism
to avoid extended priority inversion problems. Not more than one process can execute in
its critical section at one time.
 Progress: This solution is used when no one is in the critical section, and someone wants
in. Then those processes not in their reminder section should decide who should go in, in a
finite time.
 Bound Waiting: When a process makes a request for getting into critical section, there is
a specific limit about number of processes can get into their critical section. So, when the
limit is reached, the system must allow request to the process to get into its critical section.
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 wating 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.
Example
WAIT ( S ):
while ( S <= 0 );
S = S - 1;
SIGNAL ( S ):
S = S + 1;
 Process synchronization is the task of coordinating the execution of processes in a way
that no two processes can have access to the same shared data and resources.
 Four elements of critical section are 1) Entry section 2) Critical section 3) Exit section 4)
Reminder section
 A critical section is a segment of code which can be accessed by a signal process at a
specific point of time.
 Three must rules which must enforce by critical section are : 1) Mutual Exclusion 2)
Process solution 3)Bound waiting
 Mutual Exclusion is a special type of binary semaphore which is used for controlling
access to the shared resource.
 Process solution is used when no one is in the critical section, and someone wants in.
 In bound waiting solution, after a process makes a request for getting into its critical
section, there is a limit for how many other processes can get into their critical section.
 Peterson’s solution is widely used solution to critical section problems.
 Problems of the Critical Section are also resolved by synchronization of hardware
 Synchronization hardware is not a simple method to implement for everyone, so the strict
software method known as Mutex Locks was also introduced.
 Semaphore is another algorithm or solution to the critical section problem
Race Condition with Examples in OS
Each of the processes has some sharable resources and some non-shareable resources. The
sharable resources can be shared among the cooperating processes. The non-cooperating
processes don’t need to share the resources. Now, the question is what is the race condition.
When we synchronize the processes and the synchronization is not proper then the race condition
occurs. we can define the race condition as follows;
A race condition is a condition when there are many processes and every process shares the
data with each other and accessing the data concurrently, and the output of execution depends on
a particular sequence in which they share the data and access.

Now the question is how to prevent the race condition?


We can easily synchronize the processes to prevent the race condition. To prevent the race
condition, we need to ensure that only one process can access the shared data at a time. This is
the main reason why we need to synchronize the processes. we can describe the race condition as
follows;
Example of race condition
Void bankAccount(double money)
{
shared= shared + money
}
Here we have used two variables. Suppose shared is a shared variable. Now let’s say that
bankAccount function is called for its execution. The statements of this function will be executed
in the following sequence;
 The previous value of the shared variable will be loaded into one of the registers of the
CPU.
 The value of money variable will be loaded into some another register.
 The values of two variables will be stored in two registers and the result will be calculated.
 Now, assign the result to the variable share.
For example, there are two processes P1 and P2 and both P1 and P2 processes are willing to call
the function bankAccount concurrently.
suppose P1 call the function of bank account by passing the parameters of the function and the
value of the parameter is 200 and similarly, P2 call the function of the bankAccount by passing
the value of the parameter as 100.
Now, let’s suppose that the previous value of the shared variable is 1100. in this example we are
resuming that process P1 and P2 are executed on the different processors.
The result can be looks like;
 Process P1 loads 1100 into the CPU register
 P2 will load 1100 into its register.
 P1 will add 200 to its register then the result will be 1300
 The process P2 will add 100 its register and the calculated result will be 1200
 The process P1 will store 1400 in shared variable and the process P2 will store 1150 in a
shared variable.

18.Explain the concept of mutual exclusion with busy waiting in concurrent programming. Describe the potential
issues that can arise from using busy waiting to achieve mutual exclusion.[7M] [Understand]

Mutual Exclusion with Busy Waiting


Mutual exclusion is a mechanism to ensure that only one process (or person) is doing certain
things at one time, thus avoid data inconsistency. All others should be prevented from modifying
shared data until the current process finishes
 Strict Alternation
o the two processes strictly alternate in entering their CR
o the integer variable turn, initially 0, keeps track of whose turn is to enter the critical
region
o busy waiting, continuously testing a variable until some value appears, a lock that
uses busy waiting is called a spin lock
o both processes are executing in their noncritical regions
o process 0 finishes its noncritical region and goes back to the top of its loop
o unfortunately, it is not permitted to enter its CR, turn is 1 and process 1 is busy
with its nonCR
o this algorithm does avoid all races
o but violates condition 3
Figure 2.11: A proposed solution to the CR problem. (a) Process 0, (b) Process 1
 Petersons's solution
o does not require strict alternation
o this algorithm consists of two procedures
o before entering its CR, each process calls enter_region with its own process
number, 0 or 1
o after it has finished with the shared variables, the process calls leave_region to
allow the other process to enter
o consider the case that both processes call enter_region almost simultaneously
o both will store their process number in turn . Whichever store is done last is the
one that counts; the first one is overwritten and lost
o suppose that process 1 stores last , so turn is 1.
o when both processes come to the while statement, process 0 enters its critical
region
o process 1 loops until process 0 exists its CR
o no violation, implements mutual exclusion
o burns CPU cycles (requires busy waiting), can be extended to work for n processes,
but overhead, cannot be extended to work for an unknown number of processes,
unexpected effects (i.e.,priority inversion problem)
Figure 2.12: Peterson' solution for achieving mutual exclusion
19.What is the purpose of the sleep and wakeup mechanisms in an operating system's synchronization
tools? [7M][ Remember]
Sleep and Wake

(Producer Consumer problem)


Let's examine the basic model that is sleep and wake. Assume that we have two system calls
as sleep and wake. The process which calls sleep will get blocked while the process which calls
will get waked up.
There is a popular example called producer consumer problem which is the most popular
problem simulating sleep and wake mechanism.
The concept of sleep and wake is very simple. If the critical section is not empty then the process
will go and sleep. It will be waked up by the other process which is currently executing inside the
critical section so that the process can get inside the critical section.

20.What is Semaphore? How can we achieve synchronization using semaphore for producer consumer
problem? [7M] [SET-1 Feb/March 2022] [Remember]
In producer consumer problem, let us say there are two processes, one process writes
something while the other process reads that. The process which is writing something is
called producer while the process which is reading is called consumer.
In order to read and write, both of them are using a buffer. The code that simulates the sleep and
wake mechanism in terms of providing the solution to producer consumer problem is shown
below.

1.#define N 100 //maximum slots in buffer


1. #define count=0 //items in the buffer
2. void producer (void)
3. {
4. int item;
5. while(True)
6. {
7. item = produce_item(); //producer produces an item
8. if(count == N) //if the buffer is full then the producer will sleep
9. Sleep();
10. insert_item (item); //the item is inserted into buffer
11. countcount=count+1;
12. if(count==1) //The producer will wake up the
13. //consumer if there is at least 1 item in the buffer
14. wake-up(consumer);
15. }
16. }
17.
18. void consumer (void)
19. {
20. int item;
21. while(True)
22. {
23. {
24. if(count == 0) //The consumer will sleep if the buffer is empty.
25. sleep();
26. item = remove_item();
27. countcount = count - 1;
28. if(count == N-1) //if there is at least one slot available in the buffer
29. //then the consumer will wake up producer
30. wake-up(producer);
31. consume_item(item); //the item is read by consumer.
32. }
33. }
34. }

The producer produces the item and inserts it into the buffer. The value of the global variable
count got increased at each insertion. If the buffer is filled completely and no slot is available
then the producer will sleep, otherwise it keep inserting.
On the consumer's end, the value of count got decreased by 1 at each consumption. If the buffer is
empty at any point of time then the consumer will sleep otherwise, it keeps consuming the items
and decreasing the value of count by 1.
The consumer will be waked up by the producer if there is at least 1 item available in the buffer
which is to be consumed. The producer will be waked up by the consumer if there is at least one
slot available in the buffer so that the producer can write that.
Well, the problem arises in the case when the consumer got preempted just before it was about to
sleep. Now the consumer is neither sleeping nor consuming. Since the producer is not aware of
the fact that consumer is not actually sleeping therefore it keep waking the consumer while the
consumer is not responding since it is not sleeping.
This leads to the wastage of system calls. When the consumer get scheduled again, it will sleep
because it was about to sleep when it was preempted.
The producer keep writing in the buffer and it got filled after some time. The producer will also
sleep at that time keeping in the mind that the consumer will wake him up when there is a slot
available in the buffer.
The consumer is also sleeping and not aware with the fact that the producer will wake him up.
This is a kind of deadlock where neither producer nor consumer is active and waiting for each
other to wake them up. This is a serious problem which needs to be addressed.
Using a flag bit to get rid of this problem
A flag bit can be used in order to get rid of this problem. The producer can set the bit when it
calls wake-up on the first time. When the consumer got scheduled, it checks the bit.
The consumer will now get to know that the producer tried to wake him and therefore it will not
sleep and get into the ready state to consume whatever produced by the producer.
This solution works for only one pair of producer and consumer, what if there are n producers
and n consumers. In that case, there is a need to maintain an integer which can record how many
wake-up calls have been made and how many consumers need not sleep. This integer variable is
called semaphore. We will discuss more about semaphore later in detail.
SEMAPHORES:
Semaphores are just normal variables used to coordinate the activities of multiple processes in a
computer system. They are used to enforce mutual exclusion, avoid race conditions and implement
synchronization between processes.
The process of using Semaphores provides two operations: wait (P) and signal (V). The wait operation
decrements the value of the semaphore, and the signal operation increments the value of the semaphore.
When the value of the semaphore is zero, any process that performs a wait operation will be blocked
until another process performs a signal operation.
Semaphores are used to implement critical sections, which are regions of code that must be executed by
only one process at a time. By using semaphores, processes can coordinate access to shared resources,
such as shared memory or I/O devices.
Semaphores are of two types:
1. BinarySemaphore –This is also known as a mutex lock. It can have only two values – 0 and 1. Its
value is initialized to 1. It is used to implement the solution of critical section problems with multiple
processes.
2. CountingSemaphore – Its value can range over an unrestricted domain. It is used to control access
to a resource that has multiple instances.
First, look at two operations that can be used to access and change the value of the semaphore variable.

Some points regarding P and V operation:


1. P operation is also called wait, sleep, or down operation, and V operation is also called signal, wake-
up, or up operation.
2. Both operations are atomic and semaphore(s) is always initialized to one. Here atomic means that
variable on which read, modify and update happens at the same time/moment with no pre-emption
i.e. in-between read, modify and update no other operation is performed that may change the
variable.
3. A critical section is surrounded by both operations to implement process synchronization. See the
below image. The critical section of Process P is in between P and V operation.

Now, let us see how it implements mutual exclusion. Let there be two processes P1 and P2 and a
semaphore s is initialized as 1. Now if suppose P1 enters in its critical section then the value of
semaphore s becomes 0. Now if P2 wants to enter its critical section then it will wait until s > 0, this
can only happen when P1 finishes its critical section and calls V operation on semaphore s.
This way mutual exclusion is achieved. Look at the below image for details which is a Binary
semaphore.

The description above is for binary semaphore which can take only two values 0 and 1 and ensure
mutual exclusion. There is one other type of semaphore called counting semaphore which can take
values greater than one.
Now suppose there is a resource whose number of instances is 4. Now we initialize S = 4 and the rest is
the same as for binary semaphore. Whenever the process wants that resource it calls P or waits for
function and when it is done it calls V or signal function. If the value of S becomes zero then a process
has to wait until S becomes positive. For example, Suppose there are 4 processes P1, P2, P3, P4, and
they all call wait operation on S(initialized with 4). If another process P5 wants the resource then it
should wait until one of the four processes calls the signal function and the value of semaphore
becomes positive.
Limitations :
1. One of the biggest limitations of semaphore is priority inversion.
2. Deadlock, suppose a process is trying to wake up another process that is not in a sleep state.
Therefore, a deadlock may block indefinitely.
3. The operating system has to keep track of all calls to wait and signal the semaphore.
Problem in this implementation of a semaphore:
The main problem with semaphores is that they require busy waiting, If a process is in the critical
section, then other processes trying to enter the critical section will be waiting until the critical section
is not occupied by any process. Whenever any process waits then it continuously checks for semaphore
value (look at this line while (s==0); in P operation) and waste CPU cycle.

Advantages of Semaphores:

 A simple and effective mechanism for process synchronization


 Supports coordination between multiple processes
 Provides a flexible and robust way to manage shared resources.
 It can be used to implement critical sections in a program.
 It can be used to avoid race conditions.

Disadvantages of Semaphores:

 It Can lead to performance degradation due to overhead associated with wait and signal operations.
 Can result in deadlock if used incorrectly.

21.What is a mutex (mutual exclusion) in the context of concurrent programming and operating systems?
[7M][Remember]
What is Mutex?
Mutex is a mutual exclusion object that synchronizes access to a resource. It is created with a unique
name at the start of a program. The mutex locking mechanism ensures only one thread can acquire the
mutex and enter the critical section. This thread only releases the mutex when it exits in the critical
section.
It is a special type of binary semaphore used for controlling access to the shared resource. It includes a
priority inheritance mechanism to avoid extended priority inversion problems. It allows current higher
priority tasks to be kept in the blocked state for the shortest time possible. However, priority inheritance
does not correct priority inversion but only minimizes its effect.

Example

This is shown with the help of the following example,

1. wait (mutex);
2. .....
3. Critical Section
4. .....
5. signal (mutex);

Use of Mutex

A mutex provides mutual exclusion, either producer or consumer who can have the key (mutex) and
proceed with their work. As long as the producer fills the buffer, the user needs to wait, and vice versa. In
Mutex lock, all the time, only a single thread can work with the entire buffer.

When a program starts, it requests the system to create a mutex object for a given resource. The system
creates the mutex object with a unique name or ID. Whenever the program thread wants to use the
resource, it occupies lock on mutex object, utilizes the resource and after use, it releases the lock on
mutex object. Then the next process is allowed to acquire the lock on the mutex object.

Meanwhile, a process has acquired the lock on the mutex object, and no other thread or process can
access that resource. If the mutex object is already locked, the process desiring to acquire the lock on the
mutex object has to wait and is queued up by the system till the mutex object is unlocked.

Advantages of Mutex
o Mutex is just simple locks obtained before entering its critical section and then releasing it.
o Since only one thread is in its critical section at any given time, there are no race conditions, and
data always remain consistent.

Disadvantages of Mutex
o If a thread obtains a lock and goes to sleep or is preempted, then the other thread may not move
forward. This may lead to starvation.
o It can't be locked or unlocked from a different context than the one that acquired it.
o Only one thread should be allowed in the critical section at a time.
o The normal implementation may lead to a busy waiting state, which wastes CPU time.

22.Explain the basic structure of a monitor and how it encapsulates data and synchronization operations
within a single construct. [7M] [Knowledge]
MONITORS:
SCHEMATIC VIEW OF MONITORS.
What is Monitor?
It is a synchronization technique that enables threads to mutual exclusion and the wait() for a
given condition to become true. It is an abstract data type. It has a shared variable and a collection
of procedures executing on the shared variable. A process may not directly access the shared data
variables, and procedures are required to allow several processes to access the shared data
variables simultaneously.
At any particular time, only one process may be active in a monitor. Other processes that require
access to the shared variables must queue and are only granted access after the previous process
releases the shared variables.
Syntax:
The syntax of the monitor may be used as:
1. monitor {
2.
3. //shared variable declarations
4. data variables;
5. Procedure P1() { ... }
6. Procedure P2() { ... }

7. Procedure Pn() { ... }


8. Initialization Code() { ... }
9. }
Advantages and Disadvantages of Monitor
Various advantages and disadvantages of the monitor are as follows:
Advantages
1. Mutual exclusion is automatic in monitors.
2. Monitors are less difficult to implement than semaphores.
3. Monitors may overcome the timing errors that occur when semaphores are used.
4. Monitors are a collection of procedures and condition variables that are combined in a
special type of module.
Disadvantages
1. Monitors must be implemented into the programming language.
2. The compiler should generate code for them.
3. It gives the compiler the additional burden of knowing what operating system features is
available for controlling access to crucial sections in concurrent processes.
Main Differences between the Semaphore and Monitor
Here, you will learn the main differences between the semaphore and monitor. Some of the main
differences are as follows:
1. A semaphore is an integer variable that allows many processes in a parallel system to
manage access to a common resource like a multitasking OS. On the other hand, a monitor
is a synchronization technique that enables threads to mutual exclusion and the wait() for a
given condition to become true.
2. When a process uses shared resources in semaphore, it calls the wait() method and blocks
the resources. When it wants to release the resources, it executes the signal() In contrast,
when a process uses shared resources in the monitor, it has to access them via procedures.
3. Semaphore is an integer variable, whereas monitor is an abstract data type.
4. In semaphore, an integer variable shows the number of resources available in the system.
In contrast, a monitor is an abstract data type that permits only a process to execute in the
crucial section at a time.
5. Semaphores have no concept of condition variables, while monitor has condition variables.
6. A semaphore's value can only be changed using the wait() and signal() In contrast, the
monitor has the shared variables and the tool that enables the processes to access them.
Head-to-head comparison between the Semaphore and Monitor
Various head-to-head comparisons between the semaphore and monitor are as follows:
eatures Semaphore Monitor

efinition A semaphore is an integer variable that allows many It is a synchronization process that enab
processes in a parallel system to manage access to a to have mutual exclusion and the wait()
common resource like a multitasking OS. condition to become true.

yntax CLASSICAL
// Wait Operation IPC monitor {
wait(Semaphore S) { //shared variable declarations
while (S<=0); PROBLEMS data variables;
S--; Procedure P1() { ... }
} Procedure P2() { ... }
// Signal Operation .
signal(Semaphore S) { .
S++; .
} Procedure Pn() { ... }
}

asic Integer variable Abstract data type

ccess When a process uses shared resources, it calls the wait() When a process uses shared resources in
method on S, and when it releases them, it uses the signal() monitor, it has to access them via proced
method on S.

ction The semaphore's value shows the number of shared The Monitor type includes shared variab
resources available in the system. as a set of procedures that operate on the

ondition No condition variables. It has condition variables.


ariable

In summary, semaphore and monitor are two synchronization mechanisms. A semaphore is an


integer variable that performs the wait() and signal() methods. In contrast, the monitor is an
abstract data type that enables only a process to use a shared resource at a time. Monitors are
simpler to implement than semaphores, and there are fewer chances of making a mistake in
monitors than with semaphores.

Classical IPC Problems


1. Dining Philosophers Problem

2. The Readers and Writers Problem


25.Describe dining-philosopher problem? Write an algorithm to solve the problem.
using semaphores? [7M] [SET-1 July 2022] [Evaluating]
Dining philosophers problems:
There are N philosphers sitting around a circular table eating spaghetti and discussing philosphy.
The problem is that each philosopher needs 2 forks to eat, and there are only N forks, one
between each 2 philosophers. Design an algorithm that the philosophers can follow that insures
that none starves as long as each philosopher eventually stops eating, and such that the maximum
number of philosophers can eat at once.
• Philosophers eat/think
• Eating needs 2 forks
• Pick one fork at a time
• How to prevent deadlock

The problem was designed to illustrate the problem of avoiding deadlock, a system state in which
no progress is possible.
One idea is to instruct each philosopher to behave as follows:
• think until the left fork is available; when it is, pick it up
• think until the right fork is available; when it is, pick it up
• eat
• put the left fork down
• put the right fork down
• repeat from the start
This solution is incorrect: it allows the system to reach deadlock. Suppose that all five
philosophers take their left forks simultaneously. None will be able to take their right forks, and
there will be a deadlock.
We could modify the program so that after taking the left fork, the program checks to see if the
right fork is available. If it is not, the philosopher puts down the left one, waits for some time, and
then repeats the whole process. This proposal too, fails, although for a different reason. With a
little bit of bad luck, all the philosophers could start the algorithm simultaneously, picking up
their left forks, seeing that their right forks were not available, putting down their left forks,
waiting, picking up their left forks again simultaneously, and so on, forever. A situation like this,
in which all the programs continue to run indefinitely but fail to make any progress is called
starvation

The solution presented below is deadlock-free and allows the maximum parallelism for an
arbitrary number of philosophers. It uses an array, state, to keep track of whether a philosopher is
eating, thinking, or hungry (trying to acquire forks). A philosopher may move into eating state
only if neither neighbor is eating. Philosopher i's neighbors are defined by the macros LEFT and
RIGHT. In other words, if i is 2, LEFT is 1 and RIGHT is 3.

Solution:
#define N 5 /* number of philosophers */
#define LEFT (i+N-1)%N /* number of i's left neighbor */
#define RIGHT (i+1)%N/* number of i's right neighbor */
#define THINKING 0 /* philosopher is thinking */
#define HUNGRY 1 /* philosopher is trying to get forks */
#define EATING 2/* philosopher is eating */
typedef int semaphore; /* semaphores are a special kind of int */
int state[N]; /* array to keep track of everyone's state */
semaphore mutex = 1; /* mutual exclusion for critical regions */
semaphore s[N]; /* one semaphore per philosopher */
void philosopher(int i) /* i: philosopher number, from 0 to N1 */
{
while (TRUE){ /* repeat forever */ think(); /* philosopher is thinking */
take_forks(i); /* acquire two forks or block */
eat(); /* yum-yum, spaghetti */
put_forks(i); /* put both forks back on table */
}
}
void take_forks(int i) /* i: philosopher number, from 0 to N1 */
{
down(&mutex); /* enter critical region */
state[i] = HUNGRY; /* record fact that philosopher i is hungry */
test(i); /* try to acquire 2 forks */
up(&mutex); /* exit critical region */
down(&s[i]);/* block if forks were not acquired */
}
void put_forks(i) /* i: philosopher number, from 0 to N1 */
{
down(&mutex); /* enter critical region */
state[i] = THINKING; /* philosopher has finished eating */
test(LEFT); /* see if left neighbor can now eat */
test(RIGHT);/* see if right neighbor can now eat */
up(&mutex); /* exit critical region */
}
void test(i) /* i: philosopher number, from 0 to N1* /
{
if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING)
{
state[i] = EATING;
up(&s[i]);
}
}
26.State the Readers-Writers problem. Give a solution to Readers-Writer’s problem.
using Monitors. [7M] [SET-4 Jan2023] [Evaluating]
Readers Writer problems:
The dining philosophers problem is useful for modeling processes that are competing for
exclusive access to a limited number of resources, such as I/O devices. Another famous problem
is the readers and writers problem which models access to a database (Courtois et al., 1971).
Imagine, for example, an airline reservation system, with many competing processes wishing to
read and write it. It is acceptable to have multiple processes reading the database at the same
time, but if one process is updating (writing) the database, no other process may have access to
the database, not even a reader. The question is how do you program the readers and the writers?
One solution is shown below.
Solution to Readers Writer problems
typedef int semaphore; /* use your imagination */
semaphore mutex = 1; /* controls access to 'rc' */
semaphore db = 1; /* controls access to the database */
int rc = 0; /* # of processes reading or wanting to */
void reader(void)
{
while (TRUE)
{ /* repeat forever */
down(&mutex); /* get exclusive access to 'rc' */
rc = rc + 1; /* one reader more now */
if (rc == 1) down(&db);/* if this is the first reader ... */
up(&mutex); /* release exclusive access to 'rc' */
read_data_base(); /* access the data */
down(&mutex); /* get exclusive access to 'rc' */
rc = rc 1;/* one reader fewer now */
if (rc == 0) up(&db);/* if this is the last reader ... */
up(&mutex);/* release exclusive access to 'rc' */
use_data_read(); /* noncritical region */
}
}
void writer(void)
{
while (TRUE)
{ /* repeat forever */
think_up_data(); /* noncritical region */
down(&db); /* get exclusive access */
write_data_base(); /* update the data */
up(&db); /* release exclusive access */
}
}
In this solution, the first reader to get access to the data base does a down on the
semaphore db. Subsequent readers merely have to increment a counter, rc. As readers
leave, they decrement the counter and the last one out does an up on the semaphore,
allowing a blocked writer, if there is one, to get in.

You might also like