Uploaded by No One

OPERATING SYSTEM lab manual

advertisement
OPERATING SYSTEM
ETCS-352
Faculty Name:-
Student Name:Roll No:Semester:- 6th Sem
Maharaja Agrasen Institute of Technology, PSP Area,
Sector - 22, Rohini, New Delhi – 110085
INDEX
Exp
No
1.
2.
3.
4.
5.
Experiment Name
Introduction and
installation of Linux
Operating System
Introduction of
Basics Files,
Directories, System
Commands of Linux
I. Write a script to
find the greatest
of three numbers
(numbers passed
as command line
parameters)
II. Write a script to
check whether
the given no. is
even/odd.
III. Write a script to
check whether
the given no. is
prime or not.
IV. Write a script to
check whether
the given input is
a number or a
string.
Write a program to
implement CPU
scheduling for first
come first serve.
Write a program to
implement CPU
scheduling for
shortest job first.
6.
Write a program to
perform priority
scheduling
7.
Write a program to
implement CPU
scheduling for Round
Robin.
8.
Write a program for
page replacement
policy using:a) LRU
b) FIFO
Date of
Performance
Date of
Checking
R1
(3)
R2
(3)
R3
(3)
R4
(3)
R5
(3)
Total
Marks
(15)
Signature
c) Optimal
9.
10.
11.
Write a program to
implement first fit,
best fit and worst fit
algorithm for
memory
management.
Write a program to
implement
reader/writer
problem using
semaphore.
Write a program to
implement Banker’s
algorithm for
deadlock avoidance
Overall Comments:
Signature:
Faculty Name: Dr. Sandeep Tayal
EXPERIMENT 1
Aim: Introduction and installation of Linux Operating System
Introduction:
Linux is a family of free and open-source operating systems based on the Linux kernel. Operating
systems based on Linux are known as Linux distributions or distros. Examples include Debian, Ubuntu,
Fedora, CentOS, Gentoo, Arch Linux, and many others.
The Linux kernel has been under active development since 1991, and has proven to be extremely versatile
and adaptable. You can find computers that run Linux in a wide variety of contexts all over the world,
from web servers to cell phones. Today, 90% of all cloud infrastructure and 74% of the world’s
smartphones are powered by Linux.
However, newcomers to Linux may find it somewhat difficult to approach, as Linux filesystems have a
different structure than those found on Windows or MacOS. Additionally, Linux-based operating systems
depend heavily on working with the command line interface, while most personal computers rely on
graphical interfaces.
We need access to a computer running a Linux-based operating system. This can either be a virtual
private server which you’ve connected to with SSH or your local machine. Note that this tutorial was
validated using a Linux server running Ubuntu 20.04, but the examples given should work on a computer
running any version of any Linux distribution.
Linux Distributions:
Linux distribution is an operating system that is made up of a collection of software based on Linux
kernel or you can say distribution contains the Linux kernel and supporting libraries and software. And
you can get Linux based operating system by downloading one of the Linux distributions and these
distributions are available for different types of devices like embedded devices, personal computers, etc.
Around 600 + Linux Distributions are available and some of the popular Linux distributions are:
MX Linux
Manjaro
Linux Mint
elementary
Ubuntu
Debian
Solus
Fedora
Installation of Ubuntu 20.04
System Requirements:
Ubuntu 20.04 Server Edition provides a common, minimalist base for a variety of server applications,
such as file/print services, web hosting, email hosting, etc. This version supports four 64-bit architectures:
amd64 (Intel/AMD 64-bit)
arm64 (64-bit ARM)
ppc64el (POWER8 and POWER9)
s390x (IBM Z and LinuxONE)
Download Installation Media:
Step 1. Download the Installation Media, In a web browser, visit the Ubuntu download page and pick the
Ubuntu version suitable for your machine. The most popular versions include:
Ubuntu Desktop
Ubuntu Server
Ubuntu Derivatives
Step 2. Once we find the version you need, click the green Download button. You’ll be taken to a thankyou page, and your download should start. (We will download and install Ubuntu 20.04 for desktops.)
The download is an .iso file. We can use it to create a bootable USB drive.
Step 3. Save the file to a location of your choice.
Create Bootable USB
Use Balena Etcher to burn the .iso file to the USB drive.
1. Open a search dialog, and type create startup.
2. If it’s not installed, the Software Center will offer the option to install it – choose the option for
USB drive, then open the utility.
3. In the top pane, click Other, then browse and select the Ubuntu 20.04 .iso file you downloaded.
4. In the bottom pane, select your USB drive.
5. Click Make startup disk.
Boot up Ubuntu from USB
1. Turn off your system. Make sure you remove all other USB devices, such as printers, memory cards,
etc.
2. Insert the Ubuntu USB drive into the system and turn on your machine. There are two possible
scenarios:
a. The computer boots the USB drive automatically.
b. You need to manually configure USB booting in the Boot Menu or BIOS/UEFI.
3. To manually configure the boot order, tap the boot menu key about once or twice per second as soon
as the computer powers on.
Install Ubuntu Using the guided installer
1. Click install Ubuntu
2. Select Language and Keyboard Layout.
a. Normal Installation – This is the full Ubuntu Desktop experience, with office software, games,
and media players.
b. Minimal Installation – Choose this to save disk space, especially if you won’t be using media
players or productivity software.
3. Select disk partition for installation
4. Select timezone
5. Create user account and password
6. Click continue and wait till the installation completes successfully.
7. Restart the PC and start using Ubuntu 20.04
Viva Questions:
Q1: What is an operating system? What are the functions of the operating system?
Ans: An Operating System (OS) is an interface between a computer user and computer hardware. An operating
system is a software which performs all the basic tasks like file management, memory management, process
management, handling input and output, and controlling peripheral devices such as disk drives and printers.
Q2: What is Linux?
Ans: Linux is an open-source operating system like other operating systems such as Microsoft Windows,
Apple Mac OS, iOS, Google android, etc. Operating systems based on Linux are known as Linux
distributions or distros.
Q3: Name some popular Linux Distrubutions.
Ans:







MX Linux
Manjaro
Linux Mint
Ubuntu
Debian
Solus
Fedora
EXPERIMENT 2
Aim: Introduction of basic files, directories, system commands of Linux.
Linux Files
A Linux file system is a structured collection of files on a disk drive or a partition. A partition is a
segment of memory and contains some specific data. In our machine, there can be various partitions of
the memory. Generally, every partition contains a file system.
The general-purpose computer system needs to store data systematically so that we can easily access the
files in less time. It stores the data on hard disks (HDD) or some equivalent storage type. There may be
below reasons for maintaining the file system:
 Primarily the computer saves data to the RAM storage; it may lose the data if it gets turned off.
However, there is non-volatile RAM (Flash RAM and SSD) that is available to maintain the data
after the power interruption.
 Data storage is preferred on hard drives as compared to standard RAM as RAM costs more than
disk space. The hard disk costs are dropping gradually compared to the RAM.
The Linux file system contains the following sections:
 The root directory (/)
 A specific data storage format (EXT3, EXT4, BTRFS, XFS and so on)
 A partition or logical volume having a particular file system.
Linux file system is generally a built-in layer of a Linux operating system used to handle the data
management of the storage. It helps to arrange the file on the disk storage. It manages the file name, file
size, creation date, and much more information about a file. If we have an unsupported file format in our
file system, we can download software to deal with it.
Linux file system has a hierarchal file structure as it contains a root directory and its subdirectories. All
other directories can be accessed from the root directory. A partition usually has only one file system, but
it may have more than one file system. A file system is designed in a way so that it can manage and
provide space for non-volatile storage data. All file systems required a namespace that is a naming and
organizational methodology. The namespace defines the naming process, length of the file name, or a
subset of characters that can be used for the file name. It also defines the logical structure of files on a
memory segment, such as the use of directories for organizing the specific files. Once a namespace is
described, a Metadata description must be defined for that particular file.
The data structure needs to support a hierarchical directory structure; this structure is used to describe the
available and used disk space for a particular block. It also has the other details about the files such as file
size, date & time of creation, update, and last modified. Also, it stores advanced information about the
section of the disk, such as partitions and volumes.
The advanced data and the structures that it represents contain the information about the file system
stored on the drive; it is distinct and independent of the file system metadata.
Linux Directories
1. General Files – It is also called ordinary files. It may be an image, video, program, or simple text files.
These types of files can be in ASCII or Binary format. It is the most commonly used file in the Linux
system.
2. Directory Files – These types of files are a warehouse for other file types. It may be a directory file
within a directory (subdirectory).
3. Device Files – In a Windows-like operating system, devices like CD-ROM, and hard drives are
represented as drive letters like F: G: H whereas in the Linux system device are represented as files.
As for example, /dev/sda1, /dev/sda2 and so on.
These are the common top-level directories associated with the root directory:
 /bin – binary or executable programs.
 /etc – system configuration files.
 /home – home directory. It is the default current directory.
 /opt – optional or third-party software.
 /tmp – temporary space, typically cleared on reboot.
 /usr – User related programs.
 /var – log files.
Some other directories in the Linux system:
 /boot- It contains all the boot-related information files and folders such as conf, grub, etc.
 /dev – It is the location of the device files such as dev/sda1, dev/sda2, etc.
 /lib – It contains kernel modules and a shared library.
 /lost+found – It is used to find recovered bits of corrupted files.
 /media – It contains subdirectories where removal media devices inserted.
 /mnt – It contains temporary mount directories for mounting the file system.
 /proc – It is a virtual and pseudo-file system to contains info about the running processes with a
specific process ID or PID.
 /run – It stores volatile runtime data.
 /sbin – binary executable programs for an administrator.
 /srv – It contains server-specific and server-related files.
 /sys – It is a virtual filesystem for modern Linux distributions to store and allows modification of
the devices connected to the system.
System Commands of Linux
1. curl: curl transfers a URL. Use this command to test an application's endpoint or connectivity to an
upstream service endpoint. curl can be useful for determining if your application can reach another
service, such as a database, or checking if your service is healthy.
2. python -m json.tool / jq: After you issue curl, the output of the API call may be difficult to read.
Sometimes, you want to pretty-print the JSON output to find a specific entry. Python has a built-in
JSON library that can help with this. You use python -m json.tool to indent and organize the JSON.
To use Python's JSON module, pipe the output of a JSON file into the python -m json.tool command.
3. ls: ls lists files in a directory. Sysadmins and developers issue this command quite often. In the
container space, this command can help determine your container image's directory and files. Besides
looking up your files, ls can help you examine your permissions. In the example below, you can't run
myapp because of a permissions issue. When you check the permissions using ls -l, you realize that
the permissions do not have an "x" in -rw-r--r--, which are read and write only.
4. tail: tail displays the last part of a file. You usually don't need every log line to troubleshoot. Instead,
you want to check what your logs say about the most recent request to your application. For example,
you can use tail to check what happens in the logs when you make a request to your Apache HTTP
server.
5. cat: cat concatenates and prints files. You might issue cat to check the contents of your dependencies
file or to confirm the version of the application that you have already built locally.
6. grep: grep searches file patterns. If you are looking for a specific pattern in the output of another
command, grep highlights the relevant lines.
7. ps: The ps command, part of the procps-ng package which provides useful commands for
investigating process IDs, shows the status of a running process.
8. env: env allows you to set or print the environment variables.
9. top: top displays and updates sorted process information. Use this monitoring tool to determine which
processes are running and how much memory and CPU they consume.
10. netstat: netstat shows the network status. This command shows network ports in use and their
incoming connections.
Viva Questions:
Q1: What are some of the options available in UNIX command ps?
Ans:
Option
Description
-d
Displays all processes with the exception of session leaders.
-e
Displays all processes.
-f
Displays a full listing.
-glist
Displays data for the list of group leader IDs.
Q2: What are different sections of Linux File System?
Ans: The Linux file system contains the following sections:
 The root directory (/)
 A specific data storage format (EXT3, EXT4, BTRFS, XFS and so on)
 A partition or logical volume having a particular file system.
Q3: Name some directories in Linux System.
Ans:














/bin – binary or executable programs.
/etc – system configuration files.
/home – home directory. It is the default current directory.
/opt – optional or third-party software.
/tmp – temporary space, typically cleared on reboot.
/usr – User related programs.
/var – log files.
/boot- It contains all the boot-related information files and folders such as conf, grub, etc.
/dev – It is the location of the device files such as dev/sda1, dev/sda2, etc.
/lib – It contains kernel modules and a shared library.
/media – It contains subdirectories where removal media devices inserted.
/run – It stores volatile runtime data.
/sbin – binary executable programs for an administrator.
/srv – It contains server-specific and server-related files.
EXPERIMENT 3(i)
Aim: Write a script to find greatest of three numbers (numbers passed as command line
parameters)
Code:
max=$1
if [ $max -lt $2 ]
then
max=$2
fi
if [ $max -lt $3 ]
then
max=$3
fi
echo "Greatest of $1, $2, $3 is $max"
Output:
EXPERIMENT 3(ii)
Aim: Write a script to check whether the given number is even/odd.
Code:
num=$1
if [ `expr $num % 2` -eq 0 ]
then
echo "$num is even"
else
echo "$num is odd"
fi
Output:
EXPERIMENT 3(iii)
Aim: Write a script to check whether the given number is prime or not.
Code:
echo "Enter the number"
read num
i=2
flag=0
while [ $i -lt `expr $num / 2` ]
do
if [ `expr $num % $i` == 0 ]
then
flag=1
fi
i=`expr $i + 1`
done
if [ $flag -eq 0 ]
then
echo "$num is prime"
else
echo "$num is not prime"
fi
Output:
EXPERIMENT 3(iv)
Aim: Write a script to check whether the given input is a number or a string.
Code:
echo "Enter some value"
read val
if [[ $val =~ [0-9] ]]
then
echo "$val is a number"
elif [[ $val == [a-zA-Z]* ]]
then
echo "$val is an string"
fi
Output:
Viva Questions:
Q1: What is Bash.
Ans: Bash is a command line interpreter that typically runs in a text window where user can interpret commands to
carry out various actions.
Q2: How to run Bash script?
Ans: sh filename.sh
Q3: What is the command to take input in bash? Give example.
Ans: Command used to take input is: read
For ex: read val
Q4: What is the command to print in bash? Give example.
Ans: Command used to take input is: echo
For ex: echo "$val is a number"
EXPERIMENT 4
Aim: Write a program to implement CPU scheduling for first come first serve.
Code:
echo "Enter the number of tasks"
read n
for((i=0;i<$n;i++))
do
echo "Enter the pid"
read pid[$i]
echo "Enter the arrival time"
read arrival[$i]
echo "Enter the burst time"
read burst[$i]
done
#sort
for((i=0;i<`expr $n-1`;i++))
do
for((j=0;j<`expr $n-$i-1`;j++))
do
if [ ${arrival[$j]} -gt ${arrival[$((j+1))]} ]
then
temp=${arrival[$j]}
arrival[$j]=${arrival[$((j+1))]}
arrival[$((j+1))]=$temp
temp=${pid[$j]}
pid[$j]=${pid[$((j+1))]}
pid[$((j+1))]=$temp
temp=${burst[$j]}
burst[$j]=${burst[$((j+1))]}
burst[$((j+1))]=$temp
fi
done
done
time=0
averageWaiting=0
averageTurnaround=0
for((i=0;i<$n;i++))
do
if [ $time > ${arrival[$i]} ]
then
averageWaiting=`expr $averageWaiting + $time - ${arrival[$i]}`
time=`expr $time + ${burst[$i]}`
averageTurnaround=`expr $averageTurnaround + $time - ${arrival[$i]}`
else
time=`expr $time + ${arrival[$i]} + ${bust[$i]}`
averageTurnaround=`expr $averageTurnaround + ${burst[$i]}`
fi
done
averageWaiting=`expr $averageWaiting / $n`
averageTurnaround=`expr $averageTurnaround / $n`
echo "averageWaiting=$averageWaiting"
echo "averageTurnaround=$averageTurnaround"
Output:
Viva Questions:
Q1: What is Scheduling.
Ans: 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.
Q2: What is First Come First Serve Scheduling?
Ans: First come first serve (FCFS) scheduling algorithm simply schedules the jobs according to their arrival time.
The job which comes first in the ready queue will get the CPU first. The lesser the arrival time of the job, the
sooner will the job get the CPU.
Q3: What are advantages of FCFS?
Ans: Advantages are:

Simple

Easy

First come, First serve
Q4: What are disadvantages of FCFS?
Ans: Disadvantages are:
1. The scheduling method is non preemptive, the process will run to the completion.
2. Due to the non-preemptive nature of the algorithm, the problem of starvation may
occur.
3. Although it is easy to implement, but it is poor in performance since the average
waiting time is higher as compare to other scheduling algorithms.
EXPERIMENT 5
Aim: Write a program to implement CPU scheduling for shortest job first.
Code:
echo "Enter number of jobs"
read n
sum=0
for((i=0;i<$n;i++))
do
echo "Enter pid"
read pid[$i]
echo "Enter the arrival time"
read arrival[$i]
echo "Enter the burst time"
read burst[$i]
sum=`expr $sum + ${burst[$i]}`
done
for((i=0;i<`expr $n-1`;i++))
do
for((j=0;j<`expr $n-$i-1`;j++))
do
if [ ${arrival[$j]} -gt ${arrival[$((j+1))]} ]
then
temp=${arrival[$j]}
arrival[$j]=${arrival[$((j+1))]}
arrival[$((j+1))]=$temp
temp=${pid[$j]}
pid[$j]=${pid[$((j+1))]}
pid[$((j+1))]=$temp
temp=${burst[$j]}
burst[$j]=${burst[$((j+1))]}
burst[$((j+1))]=$temp
fi
done
done
time=${arrival[0]}
averageWaiting=0
averageTurnaround=0
while(true)
do
min=-1
for((i=0;i<$n;i++))
do
if [ ${arrival[$i]} -gt $time ]
then
break
fi
if [ "${pid[$i]}" = false ]
then
continue
fi
if [ $min -eq -1 ]
then
min=$i
continue
fi
if [ ${burst[$i]} -lt ${burst[$min]} ]
then
min=$i
fi
done
if [ $time -ge $sum ]
then
break
fi
if [ $min -eq -1 ]
then
time=`expr $time + 1`
continue
fi
echo "Task pid=${pid[$min]}"
echo "Time of running=$time"
averageWaiting=`expr $averageWaiting + $time - ${arrival[$min]}`
time=`expr $time + ${burst[$min]}`
echo "Time of completion=$time"
averageTurnaround=`expr $time - ${arrival[$min]} + $averageTurnaround`
pid[$min]=false
done
averageWaiting=`expr $averageWaiting / $n`
averageTurnaround=`expr $averageTurnaround / $n`
echo "Average Waiting time=$averageWaiting"
echo "Average Turn Around time=$averageTurnaround"
Output:
Viva Questions:
Q1: Name different Scheduling Queues.
Ans: 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.
Q2: What is Shortest Job First Scheduling?
Ans: SJF scheduling algorithm, schedules the processes according to their burst time.In SJF scheduling, the
process with the lowest burst time, among the list of available processes in the ready queue, is going to be
scheduled next.
Q3: What are advantages of SJF?
Ans: Advantages are:
1. Maximum throughput
2. Minimum average waiting and turnaround time
Q4: What are disadvantages of SJF?
Ans: Disadvantages are:
1. May suffer with the problem of starvation
2. It is not implementable because the exact Burst time for a process can't be known in advance.
EXPERIMENT 6
Aim: Write a program to implement priority scheduling.
Code:
echo "Priority Scheduling"
echo "Enter number of tasks"
read n
for((i=0;i<$n;i++))
do
echo "Enter PID"
read pid[$i]
echo "Enter Arrival Time"
read arrival[$i]
echo "Enter Burst Time"
read burst[$i]
echo "Enter Priority"
read priority[$i]
sum=`expr $sum + ${burst[$i]}`
done
#Sort
for((i=0;i<`expr $n - 1`;i++))
do
for((j=0;j<`expr $n - $i - 1`;j++))
do
if [ ${arrival[$j]} -gt ${arrival[$((j+1))]} ]
then
temp=${arrival[$j]}
arrival[$j]=${arrival[$((j+1))]}
arrival[$((j+1))]=$temp
temp=${pid[$j]}
pid[$j]=${pid[$((j+1))]}
pid[$((j+1))]=$temp
temp=${burst[$j]}
burst[$j]=${burst[$((j+1))]}
burst[$((j+1))]=$temp
temp=${priority[$j]}
priority[$j]=${priority[$((j+1))]}
priority[$((j+1))]=$temp
fi
done
done
time=${arrival[0]}
averageWaiting=0
averageTurnaround=0
while(true)
do
min=-1
for((i=0;i<$n;i++))
do
if [ ${arrival[$i]} -gt $time ]
then
break
fi
if [ "${pid[$i]}" = false ]
then
continue
fi
if [ $min -eq -1 ]
then
min=$i
continue
fi
if [ ${priority[$i]} -gt ${priority[$min]} ]
then
min=$i
fi
done
if [ $time -ge $sum ]
then
break
fi
if [ $min -eq -1 ]
then
time=`expr $time + 1`
continue
fi
echo "Task pid=${pid[$min]}"
echo "Time of running=$time"
echo "Priority of task=${priority[$min]}"
averageWaiting=`expr $averageWaiting + $time - ${arrival[$min]}`
time=`expr $time + ${burst[$min]}`
echo "Time of completion=$time"
averageTurnaround=`expr $time - ${arrival[$min]} + $averageTurnaround`
pid[$min]=false
done
averageWaiting=`expr $averageWaiting / $n`
averageTurnaround=`expr $averageTurnaround / $n`
echo "Average Waiting time=$averageWaiting"
echo "Average Turn Around time=$averageTurnaround"
Output:
Viva Questions:
Q1: What is Priority Scheduling?
Ans: In Priority scheduling, there is a priority number assigned to each process. In some systems, the lower the
number, the higher the priority. While, in the others, the higher the number, the higher will be the priority. The
Process with the higher priority among the available processes is given the CPU.
Q2: What are different types of Priority Scheduling?
Ans: There are two types of priority scheduling algorithm exists. One is Preemptive priority scheduling while the
other is Non Preemptive Priority scheduling.
Q3: What are advantages of Priority Scheduling?
Ans: Advantages are:


Good way to ensure processes with higher priorities are handled first.
Good when the resources are limited and priorities for each process are defined beforehand
Q4: What are disadvantages of Priority Scheduling?
Ans: Disadvantages are:



Processes with lower priority may be starved
Difficult to objectively decide which processes are given higher priority
Low priority processes will be lost if the computer crashes
EXPERIMENT 7
Aim: Write a program to implement CPU scheduling for Round Robin.
Code:
#include<iostream>
using namespace std;
void findWaitingTime(int processes[], int n, int bt[], int wt[], int quantum)
{
int rem_bt[n];
for (int i = 0 ; i < n ; i++)
rem_bt[i] = bt[i];
int t = 0;
while (1)
{
bool done = true;
for (int i = 0 ; i < n; i++)
{
if (rem_bt[i] > 0)
{
done = false;
if (rem_bt[i] > quantum)
{
t += quantum;
rem_bt[i] -= quantum;
}
else
{
t = t + rem_bt[i];
wt[i] = t - bt[i];
rem_bt[i] = 0;
}
}
}
if (done == true)
break;
}
}
void findTurnAroundTime(int processes[], int n, int bt[], int wt[], int tat[])
{
for (int i = 0; i < n ; i++)
tat[i] = bt[i] + wt[i];
}
void findavgTime(int processes[], int n, int bt[], int quantum)
{
int wt[n], tat[n], total_wt = 0, total_tat = 0;
findWaitingTime(processes, n, bt, wt, quantum);
findTurnAroundTime(processes, n, bt, wt, tat);
cout << "PID\t "<< " Burst Time "
<< "\tWait Ttime " << " \tTurn Around Time\n";
for (int i=0; i<n; i++)
{
total_wt = total_wt + wt[i];
total_tat = total_tat + tat[i];
cout << " " << i+1 << "\t\t" << bt[i] <<"\t\t"
<< wt[i] <<"\t\t " << tat[i] <<endl;
}
cout << "Average waiting time = "
<< (float)total_wt / (float)n;
cout << "\nAverage turn around time = "
<< (float)total_tat / (float)n << "\n";
}
int main()
{
int processes[] = { 1, 2, 3};
int n = sizeof processes / sizeof processes[0];
int burst_time[] = {10, 5, 8};
int quantum = 2;
findavgTime(processes, n, burst_time, quantum);
return 0;
}
Output:
Viva Questions:
Q1: Name different types of Scheduler.
Ans: Schedulers are of three types −



Long-Term Scheduler
Short-Term Scheduler
Medium-Term Scheduler
Q2: What is Round Robin Scheduling?
Ans: This is the preemptive version of first come first serve scheduling. The Algorithm focuses on Time Sharing.
In this algorithm, every process gets executed in a cyclic way. A certain time slice is defined in the system which is
called time quantum. Each process present in the ready queue is assigned the CPU for that time quantum, if the
execution of the process is completed during that time then the process will terminate else the process will go back
to the ready queue and waits for the next turn to complete the execution.
Q3: What are advantages of Round Robin Scheduling?
Ans: Advantages are:
1. It can be actually implementable in the system because it is not depending on the burst time.
2. It doesn't suffer from the problem of starvation or convoy effect.
3. All the jobs get a fare allocation of CPU.
Q4: What are disadvantages of Round Robin Scheduling?
Ans: Disadvantages are:
1. The higher the time quantum, the higher the response time in the system.
2. The lower the time quantum, the higher the context switching overhead in the system.
3. Deciding a perfect time quantum is really a very difficult task in the system.
EXPERIMENT 8
Aim: Write a program for page replacement policy using a) LRU b) FIFO c) Optimal
Code:
//LRU
#include<bits/stdc++.h>
using namespace std;
int pageFaults(int pages[], int n, int capacity)
{
unordered_set<int> s;
unordered_map<int, int> indexes;
int page_faults = 0;
for (int i=0; i<n; i++)
{
if (s.size() < capacity)
{
if (s.find(pages[i])==s.end())
{
s.insert(pages[i]);
page_faults++;
}
indexes[pages[i]] = i;
}
else
{
if (s.find(pages[i]) == s.end())
{
int lru = INT_MAX, val;
for (auto it=s.begin(); it!=s.end(); it++)
{
if (indexes[*it] < lru)
{
lru = indexes[*it];
val = *it;
}
}
s.erase(val);
s.insert(pages[i]);
page_faults++;
}
indexes[pages[i]] = i;
}
}
return page_faults;
}
int main()
{
cout<< "Program for LRU page replacement algorithm\n";
int n;
cout <<"Enter number of pages\n";
cin >> n;
cout <<"Enter pages\n";
int pages[n];
for(int i=0;i<n;i++)
cin >> pages[i];
cout<<"Enter memory capacity\n";
int capacity;
cin >> capacity;
cout << "No of page faults=" << pageFaults(pages, n, capacity) << "\n";
return 0;
}
//FIFO
// C++ implementation of FIFO page replacement
// in Operating Systems.
#include<bits/stdc++.h>
using namespace std;
int pageFaults(int pages[], int n, int capacity)
{
unordered_set<int> s;
queue<int> indexes;
int page_faults = 0;
for (int i=0; i<n; i++)
{
if (s.size() < capacity)
{
if (s.find(pages[i])==s.end())
{
s.insert(pages[i]);
page_faults++;
indexes.push(pages[i]);
}
}
else
{
if (s.find(pages[i]) == s.end())
{
int val = indexes.front();
indexes.pop();
s.erase(val);
s.insert(pages[i]);
indexes.push(pages[i]);
page_faults++;
}
}
}
return page_faults;
}
int main()
{
cout<< "Program for FIFO page replacement algorithm\n";
int n;
cout <<"Enter number of pages\n";
cin >> n;
cout <<"Enter pages\n";
int pages[n];
for(int i=0;i<n;i++)
cin >> pages[i];
cout<<"Enter memory capacity\n";
int capacity;
cin >> capacity;
cout << "No of page faults=" << pageFaults(pages, n, capacity) << "\n";
return 0;
}
//Optimal
#include <bits/stdc++.h>
using namespace std;
bool search(int key, vector<int>& fr)
{
for (int i = 0; i < fr.size(); i++)
if (fr[i] == key)
return true;
return false;
}
int predict(int pg[], vector<int>& fr, int pn, int index)
{
int res = -1, farthest = index;
for (int i = 0; i < fr.size(); i++) {
int j;
for (j = index; j < pn; j++) {
if (fr[i] == pg[j]) {
if (j > farthest) {
farthest = j;
res = i;
}
break;
}
}
if (j == pn)
return i;
}
return (res == -1) ? 0 : res;
}
int optimalPage(int pg[], int pn, int fn)
{
vector<int> fr;
int hit = 0;
for (int i = 0; i < pn; i++) {
if (search(pg[i], fr)) {
hit++;
continue;
}
if (fr.size() < fn)
fr.push_back(pg[i]);
else {
int j = predict(pg, fr, pn, i + 1);
fr[j] = pg[i];
}
}
return pn-hit;
}
int main()
{
cout<< "Program for Optimal page replacement algorithm\n";
int n;
cout <<"Enter number of pages\n";
cin >> n;
cout <<"Enter pages\n";
int pages[n];
for(int i=0;i<n;i++)
cin >> pages[i];
cout<<"Enter memory capacity\n";
int capacity;
cin >> capacity;
cout << "No of page faults=" << optimalPage(pages, n, capacity) << "\n";
return 0;
}
Output:
Viva Questions:
Q1: What is a page fault?
Ans: A page fault happens when a running program accesses a memory page that is mapped into the
virtual address space but not loaded in physical memory.
Q2: What are Page replacement algorithms?
Ans: The page replacement algorithm decides which memory page is to be replaced. The process of
replacement is sometimes called swap out or write to disk. Page replacement is done when the requested
page is not found in the main memory (page fault).
Q3: Name and explain different page replacement algorithms.
Ans:
1. Optimal Page Replacement algorithm → this algorithms replaces the page which
will not be referred for so long in future. Although it can not be practically
implementable but it can be used as a benchmark. Other algorithms are compared to
this in terms of optimality.
2. Least recent used (LRU) page replacement algorithm → this algorithm replaces
the page which has not been referred for a long time. This algorithm is just opposite to
the optimal page replacement algorithm. In this, we look at the past instead of staring
at future.
3. FIFO → in this algorithm, a queue is maintained. The page which is assigned the
frame first will be replaced first. In other words, the page which resides at the rare end
of the queue will be replaced on the every page fault.
EXPERIMENT 9
Aim: Write a program to implement first fit, best fit and worst fit algorithm for memory
management
Code:
#include<bits/stdc++.h>
using namespace std;
void firstFit(int blockSize[], int m,
int processSize[], int n)
{
int allocation[n];
memset(allocation, -1, sizeof(allocation));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (blockSize[j] >= processSize[i])
{
allocation[i] = j;
blockSize[j] -= processSize[i];
break;
}
}
}
cout << "Process No.\tProcess Size\tBlock no.\n";
for (int i = 0; i < n; i++)
{
cout << " " << i+1 << "\t\t"
<< processSize[i] << "\t\t";
if (allocation[i] != -1)
cout << allocation[i] + 1;
else
cout << "Not Allocated";
cout << endl;
}
}
void bestFit(int blockSize[], int m, int processSize[], int n)
{
int allocation[n];
memset(allocation, -1, sizeof(allocation));
for (int i=0; i<n; i++)
{
int bestIdx = -1;
for (int j=0; j<m; j++)
{
if (blockSize[j] >= processSize[i])
{
if (bestIdx == -1)
bestIdx = j;
else if (blockSize[bestIdx] > blockSize[j])
bestIdx = j;
}
}
if (bestIdx != -1)
{
allocation[i] = bestIdx;
blockSize[bestIdx] -= processSize[i];
}
}
cout << "Process No.\tProcess Size\tBlock no.\n";
for (int i = 0; i < n; i++)
{
cout << " " << i+1 << "\t\t" << processSize[i] << "\t\t";
if (allocation[i] != -1)
cout << allocation[i] + 1;
else
cout << "Not Allocated";
cout << endl;
}
}
void worstFit(int blockSize[], int m, int processSize[], int n)
{
int allocation[n];
memset(allocation, -1, sizeof(allocation));
for (int i=0; i<n; i++)
{
int wstIdx = -1;
for (int j=0; j<m; j++)
{
if (blockSize[j] >= processSize[i])
{
if (wstIdx == -1)
wstIdx = j;
else if (blockSize[wstIdx] < blockSize[j])
wstIdx = j;
}
}
if (wstIdx != -1)
{
allocation[i] = wstIdx;
blockSize[wstIdx] -= processSize[i];
}
}
cout << "Process No.\tProcess Size\tBlock no.\n";
for (int i = 0; i < n; i++)
{
cout << " " << i+1 << "\t\t" << processSize[i] << "\t\t";
if (allocation[i] != -1)
cout << allocation[i] + 1;
else
cout << "Not Allocated";
cout << endl;
}
}
int main()
{
int m,n;
cout << "Enter the number of blocks\n";
cin >> m;
int blockSize[m];
cout << "Enter the block sizes\n";
for(int i=0;i<m;i++)
cin >> blockSize[i];
cout << "Enter the number of processes\n";
cin >> n;
int processSize[n];
cout << "Enter the process sizes\n";
for(int i=0;i<n;i++)
cin >> processSize[i];
cout<<"First Fit allocation\n";
firstFit(blockSize, m, processSize, n);
cout<<"Best Fit allocation\n";
bestFit(blockSize, m, processSize, n);
cout<<"Worst Fit allocation\n";
worstFit(blockSize, m, processSize, n);
return 0 ;
}
Output:
Viva Questions:
Q1: What is Partition allocation?
Ans: In Partition Allocation, when there is more than one partition freely available to accommodate a process’s
request, a partition must be selected. To choose a particular partition, a partition allocation method is needed. A
partition allocation method is considered better if it avoids internal fragmentation. When it is time to load a
process into the main memory and if there is more than one free block of memory of sufficient size then the OS
decides which free block to allocate.
Q2: Name different placement algorithms.
Ans: Different algorithms are: First Fit, Best Fit, Worst Fit, Next Fit
Q3: Explain First Fit, Best Fit and Worst Fit algorithms.
Ans:
1. First Fit: In the first fit, the partition is allocated which is the first sufficient block from the top
of Main Memory. It scans memory from the beginning and chooses the first available block that is
large enough. Thus it allocates the first hole that is large enough.
2. Best Fit Allocate the process to the partition which is the first smallest sufficient partition among
the free available partition. It searches the entire list of holes to find the smallest hole whose size is
greater than or equal to the size of the process.
3. Worst Fit Allocate the process to the partition which is the largest sufficient among the freely
available partitions available in the main memory. It is opposite to the best-fit algorithm. It searches
the entire list of holes to find the largest hole and allocate it to process.
Q4: Which is best among above algorithms and why?
Ans: The first fit algorithm is the best algorithm among all because
1. It takes lesser time compare to the other algorithms.
2. It produces bigger holes that can be used to load other processes later on.
3. It is easiest to implement.
EXPERIMENT 10
Aim: Write a program to implement reader/writer problem using semaphore
Code:
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
sem_t wrt;
pthread_mutex_t mutex;
int cnt = 1;
int numreader = 0;
void *writer(void *wno)
{
sem_wait(&wrt);
cnt = cnt*2;
printf("Writer %d modified cnt to %d\n",(*((int *)wno)),cnt);
sem_post(&wrt);
}
void *reader(void *rno)
{
pthread_mutex_lock(&mutex);
numreader++;
if(numreader == 1) {
sem_wait(&wrt);
}
pthread_mutex_unlock(&mutex);
printf("Reader %d: read cnt as %d\n",*((int *)rno),cnt);
pthread_mutex_lock(&mutex);
numreader--;
if(numreader == 0) {
sem_post(&wrt);
}
pthread_mutex_unlock(&mutex);
}
int main()
{
pthread_t read[10],write[5];
pthread_mutex_init(&mutex, NULL);
sem_init(&wrt,0,1);
int a[10] = {1,2,3,4,5,6,7,8,9,10};
for(int i = 0; i < 10; i++) {
pthread_create(&read[i], NULL, (void *)reader, (void *)&a[i]);
}
for(int i = 0; i < 5; i++) {
pthread_create(&write[i], NULL, (void *)writer, (void *)&a[i]);
}
for(int i = 0; i < 10; i++) {
pthread_join(read[i], NULL);
}
for(int i = 0; i < 5; i++) {
pthread_join(write[i], NULL);
}
pthread_mutex_destroy(&mutex);
sem_destroy(&wrt);
return 0;
}
Output:
Viva Questions:
Q1: What is Semaphore?
Ans: Semaphore is a very significant technique to manage concurrent processes by using a simple integer value,
which is known as a semaphore. Semaphore is simply an integer variable that is shared between threads. This
variable is used to solve the critical section problem and to achieve process synchronization in the
multiprocessing environment.
Q2: Name Semaphore operations.
Ans: A semaphore has two indivisible (atomic) operations, namely: WAIT and SIGNAL .
Q3: Name different types Semaphore.
Ans: There are two types of semaphores:


Binary semaphore
Counting Semaphore
Q4: What are limitations of Semaphore?
Ans:
1. One of the biggest limitations of semaphore is priority inversion.
2. Deadlock, suppose a process is trying to wake up another process which 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 to signal the semaphore.
EXPERIMENT 11
Aim: Write a program to implement Banker’s algorithm for deadlock avoidance
Code:
#include<iostream>
using namespace std;
const int P = 5;
const int R = 3;
void calculateNeed(int need[P][R], int maxm[P][R],
int allot[P][R])
{
for (int i = 0 ; i < P ; i++)
for (int j = 0 ; j < R ; j++)
need[i][j] = maxm[i][j] - allot[i][j];
}
bool isSafe(int processes[], int avail[], int maxm[][R], int allot[][R])
{
int need[P][R];
calculateNeed(need, maxm, allot);
bool finish[P] = {0};
int safeSeq[P];
int work[R];
for (int i = 0; i < R ; i++)
work[i] = avail[i];
int count = 0;
while (count < P)
{
bool found = false;
for (int p = 0; p < P; p++)
{
if (finish[p] == 0)
{
int j;
for (j = 0; j < R; j++)
if (need[p][j] > work[j])
break;
if (j == R)
{
for (int k = 0 ; k < R ; k++)
work[k] += allot[p][k];
safeSeq[count++] = p;
finish[p] = 1;
found = true;
}
}
}
if (found == false)
{
cout << "System is not in safe state";
return false;
}
}
cout << "System is in safe state.\nSafe"
" sequence is: ";
for (int i = 0; i < P ; i++)
cout << safeSeq[i] << " ";
cout << "\n";
return true;
}
int main()
{
int processes[] = {0, 1, 2, 3, 4};
int avail[] = {3, 3, 2};
int maxm[][R] = {{7, 5, 3},
{3, 2, 2},
{9, 0, 2},
{2, 2, 2},
{4, 3, 3}};
int allot[][R] = {{0, 1, 0},
{2, 0, 0},
{3, 0, 2},
{2, 1, 1},
{0, 0, 2}};
cout << "The processes are\n";
for(int i =0;i<5;i++)
cout << processes[i] <<" ";
cout << "\nThe vailable resources are\n";
for(int i =0;i<3;i++)
cout << avail[i] <<" ";
cout << "\nMaximum Allocation Matrix\n";
for(int i =0;i<5;i++)
{
for(int j=0;j<3;j++)
cout << maxm[i][j] <<" ";
cout << "\n";
}
cout << "\nAllocated Resources Matrix\n";
for(int i =0;i<5;i++)
{
for(int j=0;j<3;j++)
cout << allot[i][j] <<" ";
cout << "\n";
}
isSafe(processes, avail, maxm, allot);
return 0;
}
Output:
Viva Questions:
Q1: How process in an OS uses resources?
Ans: A process in operating system uses resources in the following way:
1) Requests a resource
2) Use the resource
3) Releases the resource
Q2: What is a Deadlock?
Ans: Deadlock is a situation where a set of processes are blocked because each process is holding a resource
and waiting for another resource acquired by some other process.
Q3: What is Bankers’s Algorithm?
Ans: The banker’s algorithm is a resource allocation and deadlock avoidance algorithm that tests for safety by
simulating the allocation for predetermined maximum possible amounts of all resources, then makes an “s-state”
check to test for possible activities, before deciding whether allocation should be allowed to continue.
Download
Study collections