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

Operating System Assignment (1) New-1

This document contains the practical file of an Operating System course submitted by a student. It includes 14 practical assignments conducted from January to April 2023. Each practical has the aim, introduction, and steps to complete the task. The practicals cover basic OS concepts, Unix/Linux environments, shell commands, file permissions and ownership.

Uploaded by

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

Operating System Assignment (1) New-1

This document contains the practical file of an Operating System course submitted by a student. It includes 14 practical assignments conducted from January to April 2023. Each practical has the aim, introduction, and steps to complete the task. The practicals cover basic OS concepts, Unix/Linux environments, shell commands, file permissions and ownership.

Uploaded by

Utkarsh Parihar
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

DR B R AMBEDKAR NATIONAL INSTITUTE OF TECHNOLOGY,

Jalandhar (PUNJAB) -144027

PRACTILE FILE

OF

OPERATING SYSTEM (CSPC-232)

SESSION: JAN-MAY(2023)

BACHELOR OF TECHNOLOGY
IN
DEPARTMENT OF ELECTRONICS & COMMUNICATION
ENGINEERING

Submitted By- Submitted To:-


Name:- Jahanvi Prajapat Dr. Prashant Kumar(Assistant Professor)
Roll no:-21104047 Department of Computer Science & Engineering

1
INDEX
S.no Date Name of Experiment Page no Remark
1 11/01/2023 OS Practical 1 1-2
2 11/01/2023 OS Practical 2 3-7
3 18/01/2023 OS Practical 3 8-16
4 25/01/2023 OS Practical 4 17
5 01/02/2023 OS Practical 5 18-20
6 22/02/2023 OS Practical 6 21
7 22/02/2023 OS Practical 7 22-23
8 01/03/2023 OS Practical 8 24-25
9 01/03/2023 OS Practical 9 26-27
10 15/03/2023 OS Practical 10 28-33
11 22/03/2023 OS Practical 11 34-42
12 29/03/2023 OS Practical 12 43-48
13 12/04/2023 OS Practical 13 49-50
14 19/04/2023 OS Practical 14 51-56

PRACTICAL :1

2
AIM 1: To understand the basics of Operating Systems.

WHAT IS OPERATING SYSTEM?


Operating system is a set of programs which manages computer hardware, software resources
and provide common services for computer program. It is a software that enables applications
to interact with a computer's hardware.

EXAMPLES OF OPERATING SYSTEM


There are various OS available in the market. These are:

 MS-Windows
 Linux
 Android
 Mac OS
 MS-DOS
TYPES OF OPERATING SYSTEM

Batch operating system


This type of operating system does not interact with the computer directly. There is an
operator which takes similar jobs having the same requirement and group them into batches.
It is a responsibility of the operator to sort jobs with similar needs
Time sharing operating systems
Each task is given some time to execute so that all the tasks work smoothly. Each user gets
the time of CPU as they use a single system. These systems are also known as multitasking
systems. Task can be from single user or different users also. The time that each task gets is
called as quantum. After this time interval is over OS switches over to the next task.
Distributed operating system
These types of the operating system is a recent advancement in the world of computer
technology and are being widely accepted all over the world and, that too, with a great pace.
Various autonomous interconnected computers communicate with each other using
shared communication network. Independent systems posses their own memory unit and
CPU. These are referred to as loosely coupled systems or distributed system.
Network operating system
These systems run on a server and provide the capability to manage data, users, groups,
security, applications, and other networking functions. These types of operating systems

3
allowed shared access of files, printers, security, applications, and other networking functions
over a small private network.
Real-Time operating systems
These types of OSs serve real-time systems. The time interval required to process and
respond to inputs is very small. This time interval is called response time.

PRACTICAL :2

4
AIM 2: To understand the UNIX/LINUX Operating Systems
Environments.

1. introduction to Unix/Linux
Unix is a computer Operating System which is capable of handling activities from multiple
users at the same time.
The main focus that was brought by the developers in this operating system was the kernel.
Unix was considered to be the heart of the operating system.
Linux is a community of open-source Unix like operating systems that are based on the Linux
kernel.
Initially, Linux was created for personal computers and gradually it was used in other
machines like servers, mainframe computers, supercomputers, etc. Nowadays, Linux is also
used in embedded systems like routers, automation controls, televisions, digital video
recorders, video game consoles, smartwatches, etc.
2.Architecture of Linux
Linux architecture has the following components:

1. Kernel: Kernel is the core of the Linux based operating system. It virtualizes the
common hardware resources of the computer to provide each process with its virtual
resources. This makes the process seem as if it is the sole process running on the
machine. The kernel is also responsible for preventing and mitigating conflicts
between different processes. Different types of the kernel are:
 Monolithic kernel
 Hybrid kernels
 Exo kernels
 Micro kernels
2. System library: Is the special types of the functions that are used to implement the
functionality of the operating system.
3. Shell: It is an interface to the kernel which hides the complexity of the kernel’s
functions from the users. It takes commands from the user and executes the kernel’s
functions.
4. Hardware layer: This layer consists all peripheral devices like RAM/HDD/CPU etc.
5. System utility: It provides the functionalities of an operating system to the user.

5
3. System call execution
A system call is a method for a computer program to request a service from the kernel of the
operating system on which it is running. A system call is a method of interacting with the
operating system via programs. A system call is a request from the computer software to an
operating system’s kernel.
The APPLICATION PROGRAM INTERFACE(API) connects the operating system’s
functions to user programs. It acts as a link between the operating system and a process,
allowing user-level programs to request operating system services. The kernel system can
only be accessed using system calls. System calls required for any programs that use
resources.
There are various situations where you must require system calls in the operating system.
Following of the situations are as follows:

1. It is must require when a file system wants to create or delete a file.


2. Network connections require the system calls to sending and receiving data packets.
3. If you want to read or write a file, you need to system calls.
4. If you want to access hardware devices, including printer, scanner, you need a system
call.
5. System calls are used to create and manage new processes.

6
4.Command structures
All the Linux/Unix commands are run in the terminal provided by the Linux system. This
terminal is just like the command prompt of windows OS. Linux/Unix commands are case-
sensitive. The terminal can be used to accomplish all the administrative tasks. This includes
package installation, file manipulation, and user management. Linux terminal is user-
interactive. The terminal outputs the result of commands which are specified by the user
itself. Execution of typed command is done only after you press the enter key.

7
PRACTICAL :3
AIM 3: To understand the concept of shell and related commands
1.concept oof shell
A shell is a special user program which provide an interface to user to use operating system
services. Shell accepts human readable commands from user and convert them something
which kernel can understand. It is a command language interpreter that execute commands
read from input devices such as keyboards or from files. The shell gets started when the user
logs in or start the terminal.
2. types of shell

1. Sh
2. Ksh
3. Csh
4. Restricted shell
5. Bourne again shell (BASH)
3.Ls command and its options
The ls is the list command in Linux. It will show the full list or content of your directory. Just
type ls and press the enter key. The whole content will be shown. ls is a command used to list
computer directories and files in Unix-like and Unix operating systems. It is developed by the
Single Unix Specification and POSIX.

ls option Description

ls -a In Linux, hidden files start with. (dot)


symbol and they are not visible in the
regular directory. The (ls -a) command
will enlist the whole list of the current
directory including the hidden files.

ls -l It will show the list in a long list


format.

ls -lh This command will show you the file


sizes in human readable format. Size of
the file is very difficult to read when
displayed in terms of byte. The (ls -lh)
command will give you the data in
terms of Mb, Gb, Tb, etc.

ls -lhS If you want to display your files in


descending order (highest at the top)

8
according to their size, then you can use
(ls -lhS) command.

ls -l - -block- It is used to display the files in a


size=[SIZE] specific size format. Here, in [SIZE]
you can assign size according to your
requirement.

ls -d */ It is used to display only subdirectories.

ls -g or ls -lG With this you can exclude column of


group information and owner.

ls -n It is used to print group ID and owner


ID instead of their names.

ls -- This command is used to print list as


colour=[VALUE] coloured or discoloured.

ls -li This command prints the index number


if file is in the first column.

ls -p It is used to identify the directory easily


by marking the directories with a slash
(/) line sign.

ls -r It is used to print the list in reverse


order.

ls -R It will display the content of the sub-


directories also.

ls -lX It will group the files with same


extensions together in the list.

ls -lt It will sort the list by displaying


recently modified filed at top.

ls ~ It gives the contents of home directory.

ls ../ It gives the contents of parent directory.

ls --version It checks the version of ls command.

4. > option for directing the output of a command.


Output Redirection The ‘> ‘ symbol is used for output (STDOUT) redirection. Example: ls -
al > listings Here the output of command ls -al is re-directed to file “listings” instead of your
screen. Note: Use the correct file name while redirecting command output to a file.

9
5.Introduction and options for Cat command
This command displays the contents of one or more files without having to open the file for
editing. The cat command has the option of displaying the file content along with the tab
space within the text.
1. Feeding output of one command to another by pipeline.
Pipe is used to combine two or more commands, and in this, the output of one command acts
as input to another command, and this command’s output may act as input to the next
command and so on. It can also be visualized as a temporary connection between two or
more commands/ programs/ processes. The command line programs that do the further
processing are referred to as filters. This direct connection between commands/ programs/
processes allows them to operate simultaneously and permits data to be transferred between
them continuously rather than having
to pass it through temporary text files or through the display screen.
Pipes are unidirectional I.e. data flows from left to right through the pipeline.
7. Ways for signing off from Linux.
a) pkill command – Kill processes by name.
b) kill command – terminate or signal a process.
c) logout command – Logout of a login shell. This command can be used by normal users to
end their own session.
8. Locating commands
locate command in Linux is used to find the files by name. There is two most widely used
file searching utilities accessible to users are called find and locate. The locate utility works
better and faster than find command counterpart because instead of searching the file system
when a file search is initiated, it would look through a database. This database contains bits
and parts of files and their corresponding paths on your system. By default, locate command
does not check whether the files found in the database still exist and it never reports files
created after the most recent update of the relevant database.
9. PATH and SHELL variable
A subset of environment variables, such as PATH, affects the behaviour of the shell itself.
Shell (local) variables – Variables that affect only the current shell. In the C shell, a set of
these shell variables have a special relationship to a corresponding set of environment
variables. These shell variables are user, term, home, and path.
10. Combining the commands.
There are several simple ways you can combine several commands on a single command
line:

 You can run a series of commands, one after the other:


 Using a semicolon (;)
 Using && and ||
 You can run more than one command concurrently:
 Using a pipe (|) or a filter with a pipe
The output from the first command is piped to the next command as the first
command is running.
11. echo and echo –e
echo by itself displays a line of text. It will take anything within the following "..." two
quotation marks, literally, and just print out as it is. However with echo -e you're making echo
to enable interpret backslash escapes.

10
12. Cal and Date command with its different options.
The Cal command is a calendar command in Linux which is used to see the calendar of a
specific month or a whole year. The rectangular bracket means it is optional, so if used
without an option, it will display a calendar of the current month and year.
the date command displays the current date and time, including the abbreviated day name,
abbreviated month name, day of the month, the time separated by colons, the time zone
name, and the year.
13. man and help command
man command in Linux is used to display the user manual of any command that we can
run on the terminal. It provides a detailed view of the command which includes NAME,
SYNOPSIS, DESCRIPTION, OPTIONS, EXIT STATUS, RETURN VALUES, ERRORS,
FILES, VERSIONS, EXAMPLES, AUTHORS.
The help command is a shell built-in internal command. It accepts a text string as the
command line argument and searches the supplied string in the shell's documents.

14. Using escape sequence.


Escape sequences are a special type of terminal input. They're designed to make it possible
for you to enter characters or events that you may not have on your physical keyboard.
15. Printf in Linux
the Printf command inserts arguments into a user-defined string of text, creating formatted
output.

11
PRACTICAL :4
AIM 4: To understand internal and external commands in Linux.

 Internal Commands: Commands which are built into the shell. For all the shell
built-in commands, execution of the same is fast in the sense that the shell doesn’t
have to search the given path for them in the PATH variable, and also no process
needs to be spawned for executing it.
Examples: source, cd, fg, etc.
 External Commands: Commands which aren’t built into the shell. When an
external command has to be executed, the shell looks for its path given in the
PATH variable, and also a new process has to be spawned and the command gets
executed. They are usually located in /bin or /usr/bin. For example, when you
execute the “cat” command, which usually is at /usr/bin, the executable
/usr/bin/cat gets executed.
Examples: ls, cat etc.

PRACTICAL:5
AIM 5: To understand the basic file attributes.

Attributes of the File

1.Name

Every file carries a name by which the file is recognized in the file system. One directory
cannot have two files with the same name.

2.Identifier

Along with the name, Each File has its own extension which identifies the type of the file.
For example, a text file has the extension .txt, A video file can have the extension .mp4.

3.Type

In a File System, the Files are classified in different types such as video files, audio files, text
files, executable files, etc.

4.Location

In the File System, there are several locations on which, the files can be stored. Each file
carries its location as its attribute.

5.Size

The Size of the File is one of its most important attribute. By size of the file, we mean the

12
number of bytes acquired by the file in the memory.

6.Protection

The Admin of the computer may want the different protections for the different files.
Therefore each file carries its own set of permissions to the different group of Users.

7.Time and Date

Every file carries a time stamp which contains the time and date on which the file is last
modified.

PRACTICAL :6

AIM 6: To understand the concept of Vi editor and related commands.

The vi editor is elaborated as visual editor. It is installed in every Unix system. In


other words, it is available in all Linux distros. It is user-friendly and works same on different
distros and platforms. It is a very powerful application. An improved version of vi editor is
vim.

The vi editor has two modes:

o Command Mode: In command mode, actions are taken on the file. The vi editor
starts in command mode. Here, the typed words will act as commands in vi editor. To
pass a command, you need to be in command mode.
o Insert Mode: In insert mode, entered text will be inserted into the file. The Esc key
will take you to the command mode from insert mode.

By default, the vi editor starts in command mode. To enter text, you have to be in insert
mode, just type 'i' and you'll be in insert mode. Although, after typing i nothing will appear
on the screen but you'll be in insert mode. Now you can type anything.

To exit from insert mode press Esc key, you'll be directed to command mode.

If you are not sure which mode you are in, press Esc key twice and you'll be in command
mode.

PRACTICAL:7

AIM 7: To understand shell scripting using variable passing commands.


A variable is a character string to which we assign a value. The value assigned could
be a number, text, filename, device, or any other type of data.
A variable is nothing more than a pointer to the actual data. The shell enables you to create,

13
assign, and delete variables.
Variable Names--
The name of a variable can contain only letters (a to z or A to Z), numbers ( 0 to 9) or the
underscore character ( _).
By convention, Unix shell variables will have their names in UPPERCASE.
The following examples are valid variable names −
_ALI
TOKEN_A
VAR_1
VAR_2
Following are the examples of invalid variable names −
2_VAR
-VARIABLE
VAR1-VAR2
VAR_A!
The reason you cannot use other characters such as !, *, or - is that these characters have a
special meaning for the shell.
Command-Line Arguments-
The command-line arguments $1, $2, $3, ...$9 are positional parameters, with $0 pointing to
the actual command, program, shell script, or function and $1, $2, $3, ...$9 as the arguments
to the command.
Following script uses various special variables related to the command line −
#!/bin/sh

echo "File Name: $0"


echo "First Parameter : $1"
echo "Second Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
Here is a sample run for the above script −
$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2

PRACTICAL :8

AIM 8: To understand shell scripting using while loops, arithmetic and

14
logical and append.
While Loops-
It is possible to use a while loop as part of the body of another while loop.
Syntax
while command1 ; # this is loop1, the outer loop
do
Statement(s) to be executed if command1 is true

while command2 ; # this is loop2, the inner loop


do
Statement(s) to be executed if command2 is true
done

Statement(s) to be executed if command1 is true


Done
Example
Here is a simple example of loop nesting. Let's add another countdown loop inside the loop
that you used to count to nine −
#!/bin/sh

a=0
while [ "$a" -lt 10 ] # this is loop1
do
b="$a"
while [ "$b" -ge 0 ] # this is loop2
do
echo -n "$b "
b=`expr $b - 1`
done
echo
a=`expr $a + 1`
done
This will produce the following result. It is important to note how echo -n works here. Here -
n option lets echo avoid printing a new line character.
0
10
210
3210
43210
543210
6543210
76543210
876543210
9876543210

15
PRACTICAL :9

AIM 9: To understand shell scripting using file text operators and other
basic operators.

There are various operators supported by each shell. We will discuss in detail about
Bourne shell (default shell) in this chapter.
We will now discuss the following operators −
 Arithmetic Operators
 Relational Operators
 Boolean Operators
 String Operators
 File Test Operators
Bourne shell didn't originally have any mechanism to perform simple arithmetic operations
but it uses external programs, either awk or expr.
The following example shows how to add two numbers −
#!/bin/sh

val=`expr 2 + 2`
echo "Total value : $val"
The above script will generate the following result −
Total value : 4
The following points need to be considered while adding −
There must be spaces between operators and expressions. For example, 2+2 is

not correct; it should be written as 2 + 2.
 The complete expression should be enclosed between ‘ ‘, called the backtick.
Arithmetic Operators
The following arithmetic operators are supported by Bourne Shell.
Assume variable a holds 10 and variable b holds 20 then −

Operator Description Example

+ (Addition) Adds values on either side of the operator `expr $a + $b` will
give 30

- (Subtraction) Subtracts right hand operand from left hand operand `expr $a - $b` will
give -10

* (Multiplication) Multiplies values on either side of the operator `expr $a \* $b` will
give 200

16
/ (Division) Divides left hand operand by right hand operand `expr $b / $a` will
give 2

% (Modulus) Divides left hand operand by right hand operand and `expr $b % $a` will
returns remainder give 0

= (Assignment) a = $b would
Assigns right operand in left operand assign value of b
into a

== (Equality) Compares two numbers, if both are same then returns true. [ $a == $b ] would
return false.

!= (Not Equality) Compares two numbers, if both are different then returns [ $a != $b ] would
true. return true.

It is very important to understand that all the conditional expressions should be inside square
braces with spaces around them, for example [ $a == $b ] is correct whereas, [$a==$b] is
incorrect.
All the arithmetical calculations are done using long integers.

Relational Operators

Bourne Shell supports the following relational operators that are specific to numeric values.
These operators do not work for string values unless their value is numeric.
For example, following operators will work to check a relation between 10 and 20 as well as
in between "10" and "20" but not in between "ten" and "twenty".
Assume variable a holds 10 and variable b holds 20 then −
Show Examples

Operato Description Example


r

-eq Checks if the value of two operands are equal or not; if yes, then the [ $a -eq $b ] is
condition becomes true. not true.

-ne Checks if the value of two operands are equal or not; if values are not
[ $a -ne $b ] is true.
equal, then the condition becomes true.

-gt Checks if the value of left operand is greater than the value of right [ $a -gt $b ] is
operand; if yes, then the condition becomes true. not true.

-lt Checks if the value of left operand is less than the value of right
[ $a -lt $b ] is true.
operand; if yes, then the condition becomes true.

-ge Checks if the value of left operand is greater than or equal to the [ $a -ge $b ] is not
value of right operand; if yes, then the condition becomes true. true.

17
-le Checks if the value of left operand is less than or equal to the value
[ $a -le $b ] is true.
of right operand; if yes, then the condition becomes true.

It is very important to understand that all the conditional expressions should be placed inside
square braces with spaces around them. For example, [ $a <= $b ] is correct whereas, [$a <=
$b] is incorrect.
Boolean Operators
The following Boolean operators are supported by the Bourne Shell.
Assume variable a holds 10 and variable b holds 20 then −
Show Examples

Operato Description Example


r

! This is logical negation. This inverts a true condition into false and
[ ! false ] is true.
vice versa.

-o This is logical OR. If one of the operands is true, then the condition [ $a -lt 20 -o $b -gt
becomes true.
100 ] is true.

-a This is logical AND. If both the operands are true, then the condition [ $a -lt20 -a $b -gt
becomes true otherwise false.
100 ] is false.

File Test Operators


We have a few operators that can be used to test various properties associated with a Unix
file.
Assume a variable file holds an existing file name "test" the size of which is 100 bytes and
has read, write and execute permission on –

Operato Description Example


r

-b file Checks if file is a block special file; if yes, then the condition [ -b $file ] is false.
becomes true.

-c file Checks if file is a character special file; if yes, then the condition [ -c $file ] is false.
becomes true.

-d file Checks if file is a directory; if yes, then the condition becomes [ -d $file ] is not true.
true.

-f file Checks if file is an ordinary file as opposed to a directory or [ -f $file ] is true.

18
special file; if yes, then the condition becomes true.

-g file Checks if file has its set group ID (SGID) bit set; if yes, then the [ -g $file ] is false.
condition becomes true.

-k file Checks if file has its sticky bit set; if yes, then the condition [ -k $file ] is false.
becomes true.

-p file Checks if file is a named pipe; if yes, then the condition becomes [ -p $file ] is false.
true.

-t file Checks if file descriptor is open and associated with a terminal; [ -t $file ] is false.
if yes, then the condition becomes true.

-r file Checks if file is readable; if yes, then the condition becomes [ -r $file ] is true.
true.

-w file Checks if file is writable; if yes, then the condition becomes true. [ -w $file ] is true.

-x file Checks if file is executable; if yes, then the condition becomes [ -x $file ] is true.
true.

-s file Checks if file has size greater than 0; if yes, then condition [ -s $file ] is true.
becomes true.

-e file Checks if file exists; is true even if file is a directory but exists. [ -e $file ] is true.

PRACTICAL :10

AIM 10: PROCESS SCHEDULING

A. FCFS

#include<iostream>
using namespace std;

void findWaitingTime(int processes[], int n,


int bt[], int wt[])
{

wt[0] = 0;

19
for (int i = 1; i < n ; i++ )
wt[i] = bt[i-1] + wt[i-1] ;
}

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 wt[n], tat[n], total_wt = 0, total_tat = 0;

findWaitingTime(processes, n, bt, wt);

findTurnAroundTime(processes, n, bt, wt, tat);

cout << "Processes "<< " Burst time "


<< " Waiting time " << " Turn 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 "
<< 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;
}

int main()
{

int processes[] = { 1, 2, 3};

20
int n = sizeof processes / sizeof processes[0];

int burst_time[] = {10, 5, 8};

findavgTime(processes, n, burst_time);
return 0;
}

B. SJF (NONPREEMPTIVE)

#include <iostream>
using namespace std;

int main() {

int A[100][4];
int i, j, n, total = 0, index, temp;
float avg_wt, avg_tat;

cout << "Enter number of process: ";


cin >> n;

cout << "Enter Burst Time:" << endl;

21
for (i = 0; i < n; i++) {
cout << "P" << i + 1 << ": ";
cin >> A[i][1];
A[i][0] = i + 1;
}

for (i = 0; i < n; i++) {


index = i;
for (j = i + 1; j < n; j++)
if (A[j][1] < A[index][1])
index = j;
temp = A[i][1];
A[i][1] = A[index][1];
A[index][1] = temp;

temp = A[i][0];
A[i][0] = A[index][0];
A[index][0] = temp;
}

A[0][2] = 0;
for (i = 1; i < n; i++) {
A[i][2] = 0;
for (j = 0; j < i; j++)
A[i][2] += A[j][1];
total += A[i][2];
}

avg_wt = (float)total / n;
total = 0;
cout << "P BT WT TAT" << endl;

for (i = 0; i < n; i++) {


A[i][3] = A[i][1] + A[i][2];
total += A[i][3];
cout << "P" << A[i][0] << " " << A[i][1] << " " << A[i][2] << " " <<
A[i][3] << endl;
}

avg_tat = (float)total / n;
cout << "Average Waiting Time= " << avg_wt << endl;
cout << "Average Turnaround Time= " << avg_tat << endl;
}

22
C. SJF (PREEMPTIVE)

#include <iostream>
#include <climits>
using namespace std;

struct Process {
int pid;
int bt;
int at;
};

void findWaitingTime(Process proc[], int n,int wt[])


{
int rt[n];

for (int i = 0; i < n; i++)


rt[i] = proc[i].bt;

int complete = 0, t = 0, minm = INT_MAX;

23
int shortest = 0, finish_time;
bool check = false;

while (complete != n) {

for (int j = 0; j < n; j++) {


if ((proc[j].at <= t) &&
(rt[j] < minm) && rt[j] > 0) {
minm = rt[j];
shortest = j;
check = true;
}
}

if (check == false) {
t++;
continue;
}

rt[shortest]--;

minm = rt[shortest];
if (minm == 0)
minm = INT_MAX;

if (rt[shortest] == 0) {

complete++;
check = false;

finish_time = t + 1;

wt[shortest] = finish_time -
proc[shortest].bt -
proc[shortest].at;

if (wt[shortest] < 0)
wt[shortest] = 0;
}

t++;
}
}

24
void findTurnAroundTime(Process proc[], int n,
int wt[], int tat[])
{

for (int i = 0; i < n; i++)


tat[i] = proc[i].bt + wt[i];
}

void findavgTime(Process proc[], int n)


{
int wt[n], tat[n], total_wt = 0,
total_tat = 0;

findWaitingTime(proc, n, wt);

findTurnAroundTime(proc, n, wt, tat);

cout << " P\t\t"


<< "BT\t\t"
<< "WT\t\t"
<< "TAT\t\t\n";

for (int i = 0; i < n; i++) {


total_wt = total_wt + wt[i];
total_tat = total_tat + tat[i];
cout << " " << proc[i].pid << "\t\t"
<< proc[i].bt << "\t\t " << wt[i]
<< "\t\t " << tat[i] << endl;
}

cout << "\nAverage waiting time = "


<< (float)total_wt / (float)n;
cout << "\nAverage turn around time = "
<< (float)total_tat / (float)n;
}

int main()
{
Process proc[] = { { 1, 6, 2 }, { 2, 2, 5 },
{ 3, 8, 1 }, { 4, 3, 0}, {5, 4, 4} };
int n = sizeof(proc) / sizeof(proc[0]);

findavgTime(proc, n);

25
return 0;
}

PRACTICAL:11

AIM 11: PROCESS SCHEDULING

A. ROUND ROBIN

#include<iostream>
using namespace std;

void findWaitingTime(int processes[], int n,

int bt[], int wt[], int quantum)


{
// Make a copy of burst times bt[] to store remaining

int rem_bt[n];
for (int i = 0 ; i < n ; i++)
rem_bt[i] = bt[i];

int t = 0;
26
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;

27
findWaitingTime(processes, n, bt, wt, quantum);

findTurnAroundTime(processes, n, bt, wt, tat);

cout << "PN\t "<< " \tBT "


<< " WT " << " \tTAT\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 "
<< 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;
}

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;
}

28
B. PRIORITY

#include<iostream>
#include<limits>
using namespace std;

class Process{
public:
string processName;
int arrivalTime;
int burstTime;
int priority;

int remainingTime;

int responseTime;
int completionTime;

int waitingTime;
int turnAroundTime;

void initialize(){
remainingTime = burstTime;

29
}
};

int main(){
int numOfProcesses;
cout << "Enter no. of processes: ";
cin >> numOfProcesses;

Process processes[numOfProcesses];

for(int n=0;n<numOfProcesses;n++){
cout << "\nEnter Process Name for " << (n+1) << ": ";
cin >> processes[n].processName;
cout << "Enter Arrival Time for Process " << (n+1) << ": ";
cin >> processes[n].arrivalTime;
cout << "Enter Burst Time for Process " << (n+1) << ": ";
cin >> processes[n].burstTime;
cout << "Enter Priority for Process " << (n+1) << ": ";
cin >> processes[n].priority;

processes[n].initialize();
}

cout << "\n" << endl;

for(int i=0;i<numOfProcesses-1;i++){
for(int j=i+1;j<numOfProcesses;j++){
if(processes[j].arrivalTime < processes[i].arrivalTime){
Process temp = processes[j];
processes[j] = processes[i];
processes[i] = temp;
}
}
}

int currentTime = 0;

while(true){

int currentHighestPriorityIndex = -1;


int currentHighestPriority = numeric_limits<int>::max();

bool isAllCompleted = true;

for(int i=0;i<numOfProcesses;i++){
if(processes[i].remainingTime > 0){
isAllCompleted = false;
if(processes[i].arrivalTime <= currentTime){
if(processes[i].priority < currentHighestPriority){
currentHighestPriority = processes[i].priority;

30
currentHighestPriorityIndex = i;
}
}

}
}

if(isAllCompleted){
break;
}

if(processes[currentHighestPriorityIndex].remainingTime ==
processes[currentHighestPriorityIndex].burstTime){
processes[currentHighestPriorityIndex].responseTime =
currentTime;
}

processes[currentHighestPriorityIndex].remainingTime--;
currentTime++;

if(processes[currentHighestPriorityIndex].remainingTime == 0){
processes[currentHighestPriorityIndex].completionTime =
currentTime;
}
}

int sumResponseTime = 0;
int sumCompletionTime = 0;
int sumWaitingTime = 0;
int sumTurnAroundTime = 0;

for(int n=0;n<numOfProcesses;n++){
cout << "\nProcess " << processes[n].processName << ":\n";
cout << "Response Time: " << processes[n].responseTime << endl;
cout << "Completion Time: " << processes[n].completionTime << endl;
processes[n].turnAroundTime = processes[n].completionTime -
processes[n].arrivalTime;
processes[n].waitingTime = processes[n].turnAroundTime -
processes[n].burstTime;
cout << "Waiting Time: " << processes[n].waitingTime << endl;
cout << "Turn Around Time: " << processes[n].turnAroundTime << "\n" <<
endl;

sumResponseTime += processes[n].responseTime;
sumCompletionTime += processes[n].completionTime;
sumWaitingTime += processes[n].waitingTime;
sumTurnAroundTime += processes[n].turnAroundTime;
}

31
cout << "\n\nAverage Response Time for " << (numOfProcesses) << "
Processes: " << (float) sumResponseTime/numOfProcesses;
cout << "\n\nAverage Completion Time for " << (numOfProcesses) << "
Processes: " << (float) sumCompletionTime/numOfProcesses;
cout << "\n\nAverage Waiting Time for " << (numOfProcesses) << " Processes: "
<< (float) sumWaitingTime/numOfProcesses;
cout << "\n\nAverage Turn Around Time for " << (numOfProcesses) << "
Processes: " << (float) sumTurnAroundTime/numOfProcesses;

return 0;
}

C. PRIORITY

#include <iostream>

using namespace std;

#define totalprocess 5

32
struct process
{
int at,bt,pr,pno;
};

process proc[50];

bool comp(process a,process b)


{
if(a.at == b.at)
{
return a.pr<b.pr;
}
else
{
return a.at<b.at;
}
}

// Using FCFS Algorithm to find Waiting time


void get_wt_time(int wt[])
{
// declaring service array that stores cumulative burst time
int service[50];

// Initialising initial elements of the arrays


service[0] = proc[0].at;
wt[0]=0;

for(int i=1;i<totalprocess;i++)
{
service[i]=proc[i-1].bt+service[i-1];

wt[i]=service[i]-proc[i].at;

// If waiting time is negative, change it into zero

if(wt[i]<0)
{
wt[i]=0;
}
}

void get_tat_time(int tat[],int wt[])


{

33
for(int i=0;i<totalprocess;i++)
{
tat[i]=proc[i].bt+wt[i];
}

void findgc()
{

int wt[50],tat[50];

double wavg=0,tavg=0;

get_wt_time(wt);
get_tat_time(tat,wt);

int stime[50],ctime[50];

stime[0] = proc[0].at;
ctime[0]=stime[0]+tat[0];

for(int i=1;i<totalprocess;i++)
{
stime[i]=ctime[i-1];
ctime[i]=stime[i]+tat[i]-wt[i];
}

cout<<"Process_no\tStart_time\tComplete_time\tTurn_Around_Time\tWaiting_Time"<<endl
;

for(int i=0;i<totalprocess;i++)
{
wavg += wt[i];
tavg += tat[i];

cout<<proc[i].pno<<"\t\t"<<
stime[i]<<"\t\t"<<ctime[i]<<"\t\t"<<
tat[i]<<"\t\t\t"<<wt[i]<<endl;
}

cout<<"Average waiting time is : ";


cout<<wavg/(float)totalprocess<<endl;
cout<<"average turnaround time : ";
cout<<tavg/(float)totalprocess<<endl;

34
}

int main()
{
int arrivaltime[] = { 1, 2, 3, 4, 5 };
int bursttime[] = { 3, 5, 1, 7, 4 };
int priority[] = { 3, 4, 1, 7, 8 };

for(int i=0;i<totalprocess;i++)
{
proc[i].at=arrivaltime[i];
proc[i].bt=bursttime[i];
proc[i].pr=priority[i];
proc[i].pno=i+1;
}

sort(proc,proc+totalprocess,comp);

findgc();

return 0;
}

35
PRACTICAL:12

AIM 12: PROCESS SYNCHRONIZATION

1. PRODUCER CONSUMER

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>

using namespace std;

#define NUM_THREADS 2

#define BUFFER_SIZE 10

typedef struct {
int buf[BUFFER_SIZE];
int w_index;
int r_index;
int filled_slots;
}CIR_BUF;

CIR_BUF CirBuf = {0};

pthread_mutex_t sync_mutex;
sem_t sem_empty_slots;
sem_t sem_filled_slots;
void *consumer(void *arg) {
while(1) {
sem_wait(&sem_filled_slots);
pthread_mutex_lock(&sync_mutex);

cout << "consumed " << CirBuf.buf[CirBuf.r_index] << std::endl <<


std::flush;
CirBuf.r_index = (CirBuf.r_index + 1)%BUFFER_SIZE;
CirBuf.filled_slots--;

pthread_mutex_unlock(&sync_mutex); /* It does not matter, you can


release lock after sending below wake up signal as well */
sem_post(&sem_empty_slots);
}
return NULL;
}

void *producer(void *arg) {


while(1) {
sem_wait(&sem_empty_slots);

36
pthread_mutex_lock(&sync_mutex);

CirBuf.buf[CirBuf.w_index] = CirBuf.w_index;
cout << "produced " << CirBuf.buf[CirBuf.w_index] << std::endl <<
std::flush;
CirBuf.w_index = (CirBuf.w_index + 1)%BUFFER_SIZE;
CirBuf.filled_slots++;

pthread_mutex_unlock(&sync_mutex);
sem_post(&sem_filled_slots);
}
return NULL;
}

int main()
{
pthread_t thread_id[NUM_THREADS];
//int thread_arg[NUM_THREADS];

if(pthread_mutex_init(&sync_mutex, NULL)) {
cout << "Mutex not init" << endl;
}
if(sem_init(&sem_empty_slots, 0, BUFFER_SIZE)) {
cout << "Init Sem empty slots failed" << endl;
}

if(sem_init(&sem_filled_slots, 0, 0)) {
cout << "Init Sem filled slots failed" << endl;
}

pthread_create(&thread_id[0], NULL, producer, NULL);


pthread_create(&thread_id[1], NULL, consumer, NULL);

pthread_join(thread_id[0], NULL);
pthread_join(thread_id[1], NULL);

pthread_mutex_destroy(&sync_mutex);
sem_destroy(&sem_empty_slots);
sem_destroy(&sem_filled_slots);
return 0;
}

37
2. READER WRITER

#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;

class monitor {
private:

int rcnt;

int wcnt;

int waitr;

int waitw;

38
pthread_cond_t canread;

pthread_cond_t canwrite;

pthread_mutex_t condlock;

public:
monitor()
{
rcnt = 0;
wcnt = 0;
waitr = 0;
waitw = 0;

pthread_cond_init(&canread, NULL);
pthread_cond_init(&canwrite, NULL);
pthread_mutex_init(&condlock, NULL);
}

void beginread(int i)
{
pthread_mutex_lock(&condlock);

// if there are active or waiting writers


if (wcnt == 1 || waitw > 0) {
// incrementing waiting readers
waitr++;

// reader suspended
pthread_cond_wait(&canread, &condlock);
waitr--;
}

// else reader reads the resource


rcnt++;
cout << "reader " << i << " is reading\n";
pthread_mutex_unlock(&condlock);
pthread_cond_broadcast(&canread);
}

void endread(int i)
{

pthread_mutex_lock(&condlock);

if (--rcnt == 0)

39
pthread_cond_signal(&canwrite);

pthread_mutex_unlock(&condlock);
}

void beginwrite(int i)
{
pthread_mutex_lock(&condlock);

if (wcnt == 1 || rcnt > 0) {


++waitw;
pthread_cond_wait(&canwrite, &condlock);
--waitw;
}
wcnt = 1;
cout << "writer " << i << " is writing\n";
pthread_mutex_unlock(&condlock);
}

void endwrite(int i)
{
pthread_mutex_lock(&condlock);
wcnt = 0;

if (waitr > 0)
pthread_cond_signal(&canread);
else
pthread_cond_signal(&canwrite);
pthread_mutex_unlock(&condlock);
}

M;

void* reader(void* id)


{
int c = 0;
int i = (int)id;
while (c < 5) {
usleep(1);
M.beginread(i);
M.endread(i);
c++;
}
}

void* writer(void* id)

40
{
int c = 0;
int i = (int)id;

while (c < 5) {
usleep(1);
M.beginwrite(i);
M.endwrite(i);
c++;
}
}

int main()
{
pthread_t r[5], w[5];
int id[5];
for (int i = 0; i < 5; i++) {
id[i] = i;
pthread_create(&r[i], NULL, &reader, &id[i]);

pthread_create(&w[i], NULL, &writer, &id[i]);


}

for (int i = 0; i < 5; i++) {


pthread_join(r[i], NULL);
}
for (int i = 0; i < 5; i++) {
pthread_join(w[i], NULL);
}
}

41
42
PRACTICAL:13

AIM 13: BANKER’S ALGORITHM

A. SAFE
#include <stdio.h>
int main()
{

int n, m, i, j, k;
n = 5;
m = 4;
int alloc[5][3] = { { 0, 1, 0},
{ 2, 0, 0},
{ 3, 0, 2 },
{ 2, 1, 1},
{ 0, 0, 2} };

int max[5][3] = { { 7, 5, 3 },
{ 3, 2, 2 },
{ 9, 0, 2 },
{ 2, 2, 2 },
{ 4, 3, 3} };

int avail[3] = { 5, 5, 2};

int f[n], ans[n], ind = 0;


for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {

int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}

43
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}

int flag = 1;

for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}

if(flag==1)
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}

return 0;
}
B. UNSAFE

#include <stdio.h>
int main()
{

int n, m, i, j, k;
n = 5;
m = 4;
int alloc[5][4] = { { 0, 1, 0,1 },
{ 2, 0, 0,0 },
{ 3, 0, 2,1 },
{ 2, 1, 1,0 },
{ 0, 0, 2,0 } };

int max[5][4] = { { 7, 5, 3, 1 },
{ 3, 2, 2, 3 },
{ 9, 0, 2, 2 },

44
{ 2, 2, 2, 1 },
{ 4, 3, 3, 3 } };

int avail[4] = { 3, 3, 2, 1 };

int f[n], ans[n], ind = 0;


for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {

int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}

if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}

int flag = 1;

for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}

if(flag==1)

45
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}

return 0;
}

PRACTICAL 14

AIM : MEMORY ALLOCATION

a) FIRST FIT
#include<bits/stdc++.h>
using namespace std;

void firstFit(int blockSize[], int m,

46
int processSize[], int n)
{

int allocation[n];

for (int i = 0; i < n; i++)


{
allocation[i]=-1;
for (int j = 0; j < m; j++)
{
if (blockSize[j] >= processSize[i])
{

allocation[i] = j;

blockSize[j] -= processSize[i];

break;
}
}
}

cout << "\nProcess 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 blockSize[] = {500, 400, 200, 300, 600};
int processSize[] = {212, 417, 312, 426};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);

47
firstFit(blockSize, m, processSize, n);

return 0 ;
}

b) BEST FIT
#include<iostream>
using namespace std;

void bestFit(int blockSize[], int m, int processSize[], int n)


{

int allocation[n];

for (int i = 0; i < n; i++)


{
allocation[i] = -1;

int best = -1;


for (int j = 0; j < m; j++)
{

48
if (blockSize[j] >= processSize[i])
{
if (best == -1)
best = j;
else if (blockSize[best] > blockSize[j])
best = j;
}
}

if (best != -1)
{

allocation[i] = best;

blockSize[best] -= processSize[i];
}
}

cout << "\nProcess 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 blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426,500};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);

bestFit(blockSize, m, processSize, n);

return 0 ;
}

49
c) WORST FIT
#include<bits/stdc++.h>
using namespace std;

void worstFit(int blockSize[], int m, int processSize[],int n)


{

int allocation[n];

for (int i=0; i<n; i++)


{
allocation[i]=-1;

int worst = -1;


for (int j=0; j<m; j++)
{
if (blockSize[j] >= processSize[i])
{
if (worst == -1)
worst = j;
else if (blockSize[worst] < blockSize[j])
worst = j;
}
}

if (worst != -1)

50
{

allocation[i] = worst;

blockSize[worst] -= processSize[i];
}
}

cout << "\nProcess 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 blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 517, 212, 426,112};
int m = sizeof(blockSize)/sizeof(blockSize[0]);
int n = sizeof(processSize)/sizeof(processSize[0]);

worstFit(blockSize, m, processSize, n);

return 0 ;

51
}

52

You might also like