OS Lab Manual 2020-21
OS Lab Manual 2020-21
LIST OF EXPERIMENTS
2. Write a C programs to 8
implement UNIX system
calls and file management
3. Write C programs to 24
demonstrate various thread
related concepts.
4. Write C programs to simulate 28
CPU scheduling algorithms:
FCFS, SJF, and Round
Robin.
6. Write C programs to 45
simulate solutions to
Classical Process
Synchronization
Problems:
Dining Philosophers,
Producer –
Consumer and Readers –
7. Write a C program to 53
simulate Bankers Algorithm
for Deadlock Avoidance.
1. Perform a case study by installing and exploring various types of operating systems on a
physical or logical (virtual) machine. (Linux Installation).
Instructions to Install Ubuntu Linux 12.04 (LTS) along with Windows Back
Up Your Existing Data!
This is highly recommended that you should take backup of your entire data before start
with the installation process.
Obtaining System Installation Media
Download latest Desktop version of Ubuntu from this link:
http://www.ubuntu.com/download/desktop
Booting the Installation System
There are several ways to boot the installation system. Some of the very popular ways are ,
Booting from a CD ROM, Booting from a USB memory stick, and Booting from TFTP.
Here we will learn how to boot installation system using a CD ROM.
Before booting the installation system, one need to change the boot order and set CD-ROM
as first boot device.
Changing the Boot Order of a Computers
As your computer starts, press the DEL, ESC, F1, F2, F8 or F10 during the initial startup screen.
Depending on the BIOS manufacturer, a menu may appear. However, consult the hardware
documentation for the exact key strokes. In my machine, its DEL key as shown in following
screenshot.
2. Find the Boot option in the setup utility. Its location depends on your BIOS.
Select the Boot option from the menu, you can now see the options Hard Drive, CD-ROM
Drive, Removable Devices Disk etc.
3. Change the boot sequence setting so that the CD-ROM is first. See the list of “Item Specific
Page 1
MCET OPERATING SYSTEMS LAB MANUAL
Help” in right side of the window and find keys which is used to toggle to change the boot
sequence.
In a few minutes installation wizard will be started. Select your language and click the
"Install Ubuntu" button to continue...
Page 2
MCET OPERATING SYSTEMS LAB MANUAL
Optionally, you can choose to download updates while installing and/or install third party
software, such as MP3 support. Be aware, though, that if you select those options, the entire
installation process will be longer!
Since we are going to create partitions manually, select Something else, then click
Continue. Keep in mind that even if you do not want to create partitions manually, it is better to
select the same option as indicated here. This would insure that the installer will not overwrite your
Windows , which will destroy your data. The assumption here is that sdb will be used just for
Ubuntu 12.04, and that there are no valuable data on it.
Where are you? Select your location and Click the "Continue" button.
Page 3
MCET OPERATING SYSTEMS LAB MANUAL
Keyboard layout
Select your keyboard layout and UK (English) and Click on “Continue” button.
Page 4
MCET OPERATING SYSTEMS LAB MANUAL
Now Ubuntu 12.04 LTS (Precise Pangolin) operating system will be installed.
Page 5
MCET OPERATING SYSTEMS LAB MANUAL
Please remove the CD and press the "Enter" key to reboot. The computer will be restarted.
In a few seconds, you should see Windows 7′s boot menu with two entires listed – Windows 7 and
Ubuntu 12.04 (LTS).
Then you may choose to boot into Windows 7 or Ubuntu 12.04 using the UP/Down arrow key.
Please select Ubuntu 12.04 (LTS) and press Enter to boot the machine in Ubuntu 12.04
Linux.
Here you can see the users on the machine, Click on the user name and enter the password
and press Enter key to login.
Page 6
MCET OPERATING SYSTEMS LAB MANUAL
Page 7
MCET OPERATING SYSTEMS LAB MANUAL
The interface between a process and an operating system is provided by system calls. In
general, system calls are available as assembly language instructions. They are also included in the
manuals used by the assembly level programmers. System calls are usually made when a process in
user mode requires access to a resource. Then it requests the kernel to provide the resource via a
system call.
As can be seen from this diagram, the processes execute normally in the user mode until a
system call interrupts this. Then the system call is executed on a priority basis in the kernel mode.
After the execution of the system call, the control returns to the user mode and execution of user
processes can be resumed.
• If a file system requires the creation or deletion of files. Reading and writing from files also
require a system call.
• Network connections also require system calls. This includes sending and receiving packets.
• Access to a hardware devices such as a printer, scanner etc. requires a system call.
Types of System Calls
Page 8
MCET OPERATING SYSTEMS LAB MANUAL
There are mainly five types of system calls. These are explained in detail as follows −
Process Control
These system calls deal with processes such as process creation, process termination etc.
File Management
These system calls are responsible for file manipulation such as creating a file, reading a
file, writing into a file etc.
Device Management
These system calls are responsible for device manipulation such as reading from device
buffers, writing into device buffers etc.
Information Maintenance
These system calls handle information and its transfer between the operating system and the
user program.
Communication
These system calls are useful for interprocess communication. They also deal with creating
and deleting a communication connection.
Some of the examples of all the above types of system calls in Windows and Unix are given
as follows −
Types of System Calls Windows Linux
WriteConsole() write()
Page 9
MCET OPERATING SYSTEMS LAB MANUAL
ALGORITHM:
Step 1: Start the program.
Step 2: Declare the variables pid and child id.
Step 3: Get the child id value using system call fork().
Step 4: If child id value is greater than zero then print as “i am in the parent process”.
Step 5: If child id! = 0 then using getpid() system call get the process id.
Step 6: Print “i am in the parent process” and print the process id.
Step 7: If child id! = 0 then using getppid() system call get the parent process id.
Step 8: Print “i am in the parent process” and print the parent process id.
Step 9: Else If child id value is less than zero then print as “i am in the child process”.
Step 10: If child id! = 0 then using getpid() system call get the process id.
Step 11: Print “i am in the child process” and print the process id.
Step 12: If child id! = 0 then using getppid() system call get the parent process id.
Step 13: Print “i am in the child process” and print the parent process id.
Step 14: Stop the program.
PROGRAM :
SOURCE CODE:
Page 10
MCET OPERATING SYSTEMS LAB MANUAL
AIM:To write the program to implement the system calls wait ( ) and exit ( ).
DESCRIPTION:
i. fork ( )
Used to create new process. The new process consists of a copy of the address space of the
original process. The value of process id for the child process is zero, whereas the value of process
id for the parent is an integer value greater than zero.
Page 11
MCET OPERATING SYSTEMS LAB MANUAL
Page 12
MCET OPERATING SYSTEMS LAB MANUAL
{
printf("fork failed");
exit(0);
} else
if(pid==0)
{ printf("\n Child process starts");
for(i=0; i<5; i++)
{ printf("\n Child process %d is called", i);
} printf("\n Child process
ends");
}
else
{ wait(0); printf("\n Parent process
ends");
} exit(0);
}
OUTPUT:
$ vi waitexit.c
$ cc waitexit.c
$ ./a.out
Child process starts
Child process 0 is called
Child process 1 is called
Child process 2 is called
Child process 3 is called
Child process 4 is called
Child process ends
Parent process ends
RESULT:
Thus the program was executed and verified successfully
Page 13
MCET OPERATING SYSTEMS LAB MANUAL
$ vi wait.c
Page 14
MCET OPERATING SYSTEMS LAB MANUAL
$ cc wait.c
$ ./a.out
CHILD: This is the child process!
CHILD: My PID is 3821
CHILD: My parent's PID is 3820
CHILD: Enter my exit status (make it small):
CHILD: I'm outta here!
PARENT: This is the parent process!
PARENT: My PID is 3820
10
PARENT: My child's PID is 3821
PARENT: I'm now waiting for my child to exit()...
PARENT: My child's exit status is: 10 PARENT:
I'm outta here!
RESULT:
Thus the program was executed and verified successfully
2. C) EXECL SYSTEM CALL
Page 15
MCET OPERATING SYSTEMS LAB MANUAL
OUTPUT:
$ vi execl.c
$ cc execl.c
$ ./a.out
Before execl a1 aaa aaa.txt abc a.out b1 b2 comm.c db db1 demo2 dir1 direc.c execl.c
f1.txt fflag.c file1 file2 fork.c m1 m2 wait.c xyz
RESULT:
Thus the program was executed and verified successfully
Page 16
MCET OPERATING SYSTEMS LAB MANUAL
Page 17
MCET OPERATING SYSTEMS LAB MANUAL
PROGRAM:
SOURCE CODE:
/* Recursively descend a directory hierarchy pointing a file */
#include<stdio.h>
#include<dirent.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h> int
main(int argc,char *argv[])
{ struct dirent *direntp; DIR *dirp; if(argc!=2)
{ printf("ussage %s directory name \n",argv[0]);
return 1;
}
if((dirp=opendir(argv[1]))==NULL)
{ perror("Failed to open directory \n");
return 1;
}
while((direntp=readdir(dirp))!=NULL)
printf("%s\n",direntp->d_name);
while((closedir(dirp)==-1)&&(errno==EINTR)); return
0;
}
OUTPUT:
$ vi direc.c
$ cc direc.c
$ ./a.out ./
f1.txt fflag.c
. ..
b2 comm.c
dir1
demo2 a1
m1 db
Page 19
MCET OPERATING SYSTEMS LAB MANUAL
a.out
direc.c db1
file1
b1 xyz
abc
aaa
file2
aaa.txt
m2
RESULT:
Thus the program was executed and verified successfully.
AIM:To write the program to implement the system calls open ( ), read ( ), write ( ) & close ().
DESCRIPTION:
The file structure related system calls available in the UNIX system let you create, open, and
close files, read and write files, randomly access files, alias and remove files, get information about
files, check the accessibility of files, change protections, owner, and group of files, and control
devices. These operations either use a character string that defines the absolute or relative path name
of a file, or a small integer called a file descriptor that identifies the I/O channel. A channel is a
connection between a process and a file that appears to the process as an unformatted stream of
bytes. The kernel presents and accepts data from the channel as a process reads and writes that
channel. To a process then, all input and output operations are synchronous and unbuffered.
SYSTEM CALLS USED:
System calls are functions that a programmer can call to perform the services of the operating
system.
Open ():
Open () system call to open a file.
open () returns a file descriptor, an integer specifying the position of this open n file in the
table of open files for the current process.
Close ():
Close () system call to close a file.
Read ():
Page 20
MCET OPERATING SYSTEMS LAB MANUAL
Value Meaning
O_RDONLY Open for reading only
O_WRONLY Open for writing only
O_RDWR Open for reading and writing
O_APPEND Open at end of file for writing
O_CREAT Create the file if it doesn't already exist
O_EXCL If set and O_CREAT set will cause open() to fail if the file already exists
O_TRUNC Truncate file size to zero if it already exists
Page 21
MCET OPERATING SYSTEMS LAB MANUAL
The write () system call is used to write data to a file or other object identified by a file
descriptor. The prototype is #include<sys/types.h> size_t write (int fildes, const void *buf,
size_t nbyte);
ALGORITHM:
Step 1: Start the program.
Step 2: Declare the structure elements.
Step 3: Create a temporary file named temp1.
Step 4: Open the file named “test” in a write mode. Step
5: Enter the strings for the file.
Step 6: Write those strings in the file named “test”. Step
7: Create a temporary file named temp2.
Step 8: Open the file named “test” in a read mode.
Step 9: Read those strings present in the file “test” and save it in temp2. Step
10: Print the strings which are read.
Step 11: Stop the program.
PROGRAM :
SOURCE CODE:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h> int
main( )
{ int fd[2];
char buf1[25]= ”just a test\n”; char buf2[50];
fd[0]=open(“file1”, O_RDWR);
fd[1]=open(“file2”, O_RDWR);
write(fd[0], buf1, strlen(buf1)); printf(“\
n Enter the text now….”); gets(buf1);
write(fd[0], buf1, strlen(buf1));
lseek(fd[0], SEEK_SET, 0);
read(fd[0], buf2, sizeof(buf1));
write(fd[1], buf2,
Page 22
MCET OPERATING SYSTEMS LAB MANUAL
sizeof(buf2)); close(fd[0]);
close(fd[1]); printf(“\n”);
return0;
}
OUTPUT:
Enter the text now….progress
Cat file1 Just a test progress
Cat file2 Just a test progress
RESULT:
Thus the program was executed successfully.
Page 23
MCET OPERATING SYSTEMS LAB MANUAL
The concept of multi-threading needs proper understanding of these two terms – a process
and a thread. A process is a program being executed. A process can be further divided into
independent units known as threads.
A thread is like a small light-weight process within a process. Or we can say a collection of
threads is what is known as a process.
Applications –
Threading is used widely in almost every field.
• Most widely it is seen over the internet now days where we are using transaction processing
of every type like recharges, online transfer, banking etc.
• Threading is a segment which divide the code into small parts that are of very light weight
and has less burden on CPU memory so that it can be easily worked out and can achieve
goal in desired field.
• The concept of threading is designed due to the problem of fast and regular changes in
technology and less the work in different areas due to less application
PROGRAM :
Page 24
MCET OPERATING SYSTEMS LAB MANUAL
SOURCE CODE:
/* Implementing a program using thread */
#include<pthread.h>
#include<stdio.h>
#define NUM_THREADS 3
int je,jo,evensum=0,sumn=0,oddsum=0,evenarr[50],oddarr[50]; void
*Even(void *threadid)
{ int i,n; je=0;
n=(int)threadid;
for(i=1;i<=n;i++)
{ if(i%2==0)
{ evenarr[je]=i;
evensum=evensum+i
; je++;
}
}}
void *Odd(void *threadid)
{ int i,n; jo=0;
n=(int)threadid;
for(i=0;i<=n;i++)
{ if(i%2!=0)
{ oddarr[jo]=i;
oddsum=oddsum+i
; jo++;
}
}
} void *SumN(void
*threadid)
{ int i,n;
n=(int)threadid;
for(i=1;i<=n;i++)
{
sumn=sumn+i;
}
} int
main()
Page 25
MCET OPERATING SYSTEMS LAB MANUAL
{
pthread_t threads[NUM_THREADS];
int i,t;
printf("Enter a number\n"); scanf("%d",&t);
pthread_create(&threads[0],NULL,Even,(void
*)t); pthread_create(&threads[1],NULL,Odd,(void
*)t);
pthread_create(&threads[2],NULL,SumN,(void *)t); for(i=0;i<NUM_THREADS;i++)
{ pthread_join(threads[i],NULL);
}
printf("The sum of first N natural nos is %d\n",sumn);
printf("The sum of first N even natural nos is %d\
n",evensum); printf("The sum of first N odd natural nos is
%d\n",oddsum); printf("The first N even natural nos is----\
n"); for(i=0;i<je;i++) printf("%d\n",evenarr[i]);
printf("The first N odd natural nos is----\
n"); for(i=0;i<jo;i++) printf("%d\
n",oddarr[i]);
pthread_exit(NULL);
}
OUTPUT:
$ vi threadf.c
$ cc threadf.c -pthread
$ ./a.out
Enter a number
12
The sum of first N natural nos is 78
The sum of first N even natural nos is 42
The sum of first N odd natural nos is 36
The first N even natural nos is----
2
4
6
8
10
12
Page 26
MCET OPERATING SYSTEMS LAB MANUAL
RESULT:
Thus the program was executed and verified successfully.
Page 27
MCET OPERATING SYSTEMS LAB MANUAL
4.AIM :Write C programs to simulate CPU scheduling algorithms: FCFS, SJF, and Round
Robin.
CPU Scheduling Algorithms:
Scheduling of processes/work is done to finish the work on time.
Below are different times with respect to a process.
Arrival Time : Time at which the process arrives in the ready queue.
Completion Time : Time at which process completes its execution.
Burst Time : Time required by a process for CPU execution.
Turn Around Time : Time Difference between completion time and arrival time.
Turn Around Time = Completion Time - Arrival Time
Waiting Time(W.T) : Time Difference between turn around time and burst time.
Waiting Time = Turn Around Time - Burst Time Why
do we need scheduling?
A typical process involves both I/O time and CPU time. In a uniprogramming system like MSDOS,
time spent waiting for I/O is wasted and CPU is free during this time. In multiprogramming
systems, one process can use CPU while another is waiting for I/O. This is possible only with
process scheduling.
Objectives of Process Scheduling Algorithm
• Max CPU utilization [Keep CPU as busy as possible] Fair allocation of CPU.
• Max throughput [Number of processes that complete their execution per time unit]
• Min turnaround time [Time taken by a process to finish execution]
• Min waiting time [Time a process waits in ready queue]
• Min response time [Time when a process produces first response] Different Scheduling
Algorithms:
First Come First Serve (FCFS): Simplest scheduling algorithm that schedules according to arrival
times of processes. First come first serve scheduling algorithm process that requests the CPU first is
allocated the CPU first. It is implemented by using the 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. FCFS is a
non – preemptive scheduling algorithm.
Note: First come first serve suffers from convoy effect.
Shortest Job First (SJF): Process which has the shortest burst time is scheduled first. If two
processes have the same bust time then FCFS is used to break the tie. It is a non-preemptive
scheduling algorithm.
Page 28
MCET OPERATING SYSTEMS LAB MANUAL
Longest Job First (LJF): It is similar to SJF scheduling algorithm. But, in this scheduling
algorithm, we give priority to the process having the longest burst time. This is non – preemptive in
nature i.e., when any process starts executing, can’t be interrupted before complete execution.
Shortest Remaining Time First (SRTF): It is preemptive mode of SJF algorithm in which jobs are
schedule according to shortest remaining time.
Longest Remaining Time First (LRTF): It is preemptive mode of LJF algorithm in which we give
priority to the process having largest burst time remaining.
Round Robin Scheduling: Each process is assigned a fixed time (Time Quantum/Time Slice) in
cyclic way. It is designed especially for the time-sharing system. 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 Round Robin scheduling, we
keep the ready queue as a FIFO queue o£ 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 o£ the ready queue. The CPU scheduler will then
select the next process in the ready queue.
Priority Based scheduling (Non - Preemptive): In this scheduling, processes are scheduled
according to their priorities, i.e., highest priority process is scheduled first. If priorities of two
processes match, then schedule according to arrival time. Here starvation of process is possible.
Highest Response Ratio Next (HRRN) In this scheduling, processes with highest response ratio is
scheduled. This algorithm avoids starvation.
Response Ratio = (Waiting Time + Burst time) / Burst time
Multilevel Queue Scheduling: According to the priority of process, processes are placed in the
different queues. Generally high priority process is placed in the top level queue. Only after
completion of processes from top level queue, lower level queued processes are scheduled. It can
suffer from starvation.
Multi level Feedback Queue Scheduling: It allows the process to move in between queues. The
idea is to separate processes according to the characteristics of their CPU bursts. If a process uses
too much CPU time, it is moved to a lower-priority queue.
Page 29
MCET OPERATING SYSTEMS LAB MANUAL
P0 0-0=0
P1 5-1=4
P2 8-2=6
P3 16 - 3 = 13
ALGORITHM:
Step 1: Start the program.
Step 2: Create the number of process.
Step 3: Get the ID and Service time for each process.
Page 30
MCET OPERATING SYSTEMS LAB MANUAL
Step 4: Initially, Waiting time of first process is zero and Total time for the first process is the
starting time of that process.
Step 5: Calculate the Total time and Processing time for the remaining processes.
Step 6: Waiting time of one process is the Total time of the previous process.
Step 7: Total time of process is calculated by adding Waiting time and Service time.
Step 8: Total waiting time is calculated by adding the waiting time for lack process.
Step 9: Total turn around time is calculated by adding all total time of each process. Step 10:
Calculate Average waiting time by dividing the total waiting time by total number of process.
Step 11: Calculate Average turn around time by dividing the total time by the number of process.
Step 12: Display the result.
Step 13: Stop the program.
PROGRAM:
SOURCE CODE:
/* A program to simulate the FCFS CPU scheduling algorithm */
#include<stdio.h> int
main()
{ char pn[10][10];
int arr[10],bur[10],star[10],finish[10],tat[10],wt[10],i,n;
int totwt=0,tottat=0;
printf("Enter the number of
processes:"); scanf("%d",&n);
for(i=0;i<n;i++)
{ printf("Enter the Process Name, Arrival Time & Burst Time:");
scanf("%s%d%d",&pn[i],&arr[i],&bur[i]);
} for(i=0;i<n;i+
+)
{
if(i==0)
{ star[i]=arr[i]; wt[i]=star[i]-
arr[i]; finish[i]=star[i]
+bur[i];
tat[i]=finish[i]-arr[i];
}
else
{ star[i]=finish[i-1];
wt[i]=star[i]-arr[i];
Page 31
MCET OPERATING SYSTEMS LAB MANUAL
finish[i]=star[i]+bur[i];
tat[i]=finish[i]-arr[i];
}
} printf("\nPName Arrtime Burtime Start TAT
Finish"); for(i=0;i<n;i++)
{ printf("\n%s\t%6d\t\t%6d\t%6d\t%6d\t%6d",pn[i],arr[i],bur[i],star[i],tat[i],finish[i]);
totwt+=wt[i]; tottat+=tat[i];
}
printf("\nAverage Waiting time:%f", (float)totwt); printf("\
nAverage Turn Around Time:%f", (float)tottat);
}
OUTPUT:
$ vi fcfs.c
$ cc fcfs.c
$ ./a.out
Enter the number of processes: 3
Enter the Process Name, Arrival Time & Burst Time: 1 2 3
Enter the Process Name, Arrival Time & Burst Time: 2 5 6
Enter the Process Name, Arrival Time & Burst Time: 3 6 7
PName Arrtime Burtime Start TAT Finish
1 2 3 2 3 5
2 5 6 5 6 11
3 6 7 11 12 18
Average Waiting time: 1.666667
Average Turn Around Time: 7.000000
RESULT:
Thus the program was executed and verified successfully.
Page 32
MCET OPERATING SYSTEMS LAB MANUAL
P0 0 5 0
P1 1 3 5
P2 2 8 14
P3 3 6 8
P0 0-0=0
P1 5-1=4
P2 14 - 2 = 12
P3 8-3=5
Page 33
MCET OPERATING SYSTEMS LAB MANUAL
Step 7: Total time of process is calculated by adding the waiting time and service time of each
process.
Step 8: Total waiting time calculated by adding the waiting time of each process.
Step 9: Total turn around time calculated by adding all total time of each process.
Step 10: Calculate average waiting time by dividing the total waiting time by total number of
process.
Step 11: Calculate average turn around time by dividing the total waiting time by total number of
process.
Step 12: Display the result.
Step 13: Stop the program.
PROGRAM:
SOURCE CODE:
/* A program to simulate the SJF CPU scheduling algorithm */
#include<stdio.h>
#include<string.h> main()
{ int i=0,pno[10],bt[10],n,wt[10],temp=0,j,tt[10]; float
sum,at;
printf("\n Enter the no of process "); scanf("\n
%d",&n); printf("\n Enter the burst time of each
process"); for(i=0;i<n;i++)
{ printf("\n p%d",i);
scanf("%d",&bt[i]);
} for(i=0;i<n-1;i+
+)
{ for(j=i+1;j<n;j++)
{ if(bt[i]>bt[j])
{ temp=bt[i];
bt[i]=bt[j];
bt[j]=temp;
temp=pno[i];
pno[i]=pno[j]
;
pno[j]=temp;
}
Page 34
MCET OPERATING SYSTEMS LAB MANUAL
}}
wt[0]=0;
for(i=1;i<n;i+
+)
{ wt[i]=bt[i-1]+wt[i-1];
sum=sum+wt[i];
}
printf("\n process no \t burst time\t waiting time \t turn around time\n"); for(i=0;i<n;i+
+)
{ tt[i]=bt[i]+wt[i];
at+=tt[i];
printf("\n p%d\t\t%d\t\t%d\t\t%d",i,bt[i],wt[i],tt[i]);
} printf("\n\n\t Average waiting time%f\n\t Average turn around time%f", sum,
at); }
OUTPUT:
$ vi sjf.c
$ cc sjf.c
$ ./a.out
Enter the no of process 5
Enter the burst time of each process
p0 1
p1 5
p2 2
p3 3
p4 4
P0 (0 - 0) + (12 - 3) = 9
P1 (3 - 1) = 2
P3 (9 - 3) + (17 - 12) = 11
Page 36
MCET OPERATING SYSTEMS LAB MANUAL
i. The waiting time for first instance of a process is calculated as: a[i].waittime=count +
a[i].arrivt.
ii. The waiting time for the rest of the instances of the process is calculated as:
a) If the time quantum is greater than the remaining burst time then waiting time is calculated
as: a[i].waittime=count + tq.
b) Else if the time quantum is greater than the remaining burst time then waiting time is
calculated as: a[i].waittime=count - remaining burst time Step 5: Calculate the average
waiting time and average turnaround time Step 6: Print the results of the step 4.
Step 7: Stop the program.
PROGRAM :
SOURCE CODE:
/* A program to simulate the Round Robin CPU scheduling algorithm */
#include<stdio.h> struct
process
{ int burst,wait,comp,f;
}p[20]={0,0}; int
main()
{ int n,i,j,totalwait=0,totalturn=0,quantum,flag=1,time=0;
printf("\nEnter The No Of Process :"); scanf("%d",&n);
printf("\nEnter The Quantum time (in
ms) :"); scanf("%d",&quantum);
for(i=0;i<n;i++)
{ printf("Enter The Burst Time (in ms) For Process #%2d :",i+1);
scanf("%d",&p[i].burst);
p[i].f=1;
} printf("\nOrder Of Execution \n"); printf("\
nProcess Starting Ending Remaining");
printf("\n\t\tTime \tTime \t Time");
while(flag==1)
{ flag=0; for(i=0;i<n;i+
+)
{ if(p[i].f==1)
{ flag=1; j=quantum; if((p[i].burst-
p[i].comp)>quantum)
{ p[i].comp+=quantum;
Page 37
MCET OPERATING SYSTEMS LAB MANUAL
} else
{ p[i].wait=time-p[i].comp;
j=p[i].burst-p[i].comp;
p[i].comp=p[i].burst;
p[i].f=0;
}
printf("\nprocess # %-3d %-10d %-10d %-10d", i+1, time, time+j,
p[i].burst-p[i].comp);
time+=j;
}
} } printf("\n\n------------------"); printf("\
nProcess \t Waiting Time TurnAround Time ");
for(i=0;i<n;i++)
{
printf("\nProcess # %-12d%-15d%-
15d",i+1,p[i].wait,p[i].wait+p[i].burst); totalwait=totalwait+p[i].wait;
totalturn=totalturn+p[i].wait+p[i].burst;
} printf("\n\nAverage\n------------------ "); printf("\
nWaiting Time: %fms",totalwait/(float)n); printf("\
nTurnAround Time : %fms\n\n",totalturn/(float)n); return
0;
}
OUTPUT:
$ vi rr.c
$ cc rr.c
$ ./a.out
Enter The No Of Process: 3
Enter The Quantum time (in ms): 5
Enter The Burst Time (in ms) For Process # 1: 25
Enter The Burst Time (in ms) For Process # 2: 30
Enter The Burst Time (in ms) For Process # 3: 54
Order Of Execution
Process Starting Ending Remaining
Time Time Time
Page 38
MCET OPERATING SYSTEMS LAB MANUAL
process # 1 0 5 20
process # 2 5 10 25
process # 3 10 15 49
process # 1 15 20 15
process # 2 20 25 20
process # 3 25 30 44
process # 1 30 35 10
process # 2 35 40 15
process # 3 40 45 39
process # 1 45 50 5
process # 2 50 55 10
process # 3 55 60 34
process # 1 60 65 0
process # 2 65 70 5
process # 3 70 75 29
process # 2 75 80 0
process # 3 80 85 24
process # 3 85 90 19
process # 3 90 95 14
process # 3 95 100 9
process # 3 100 105 4
process # 3 105 109 0
------------------
Process Waiting Time TurnAround Time
Process # 1 40 65
Process # 2 50 80
Process # 3 55 109
Average
------------------
Waiting Time: 48.333333ms
TurnAround Time: 84.666667ms
RESULT:
Page 39
MCET OPERATING SYSTEMS LAB MANUAL
5. AIM: Write C programs to simulate Intra & Inter – Process Communication (IPC)
techniques: Pipes, Messages Queues, and Shared Memory.
DESCRIPTION:
Inter Process Communication (IPC) is a mechanism that involves communication of one process
with another process. This usually occurs only in one system.
Communication can be of two types:
Between related processes initiating from only one process, such as parent and child processes.
Between unrelated processes, or two or more different processes.
Following are some important terms that we need to know before proceeding further on this topic.
Page 40
MCET OPERATING SYSTEMS LAB MANUAL
Pipes − Communication between two related processes. The mechanism is half duplex meaning the
first process communicates with the second process. To achieve a full duplex i.e., for the second
process to communicate with the first process another pipe is required.
FIFO − Communication between two unrelated processes. FIFO is a full duplex, meaning the first
process can communicate with the second process and vice versa at the same time.
Message Queues − Communication between two or more processes with full duplex capacity. The
processes will communicate with each other by posting a message and retrieving it out of the queue.
Once retrieved, the message is no longer available in the queue.
Shared Memory − Communication between two or more processes is achieved through a shared
piece of memory among all processes. The shared memory needs to be protected from each other by
synchronizing access to all the processes.
Semaphores − Semaphores are meant for synchronizing access to multiple processes. When one
process wants to access the memory (for reading or writing), it needs to be locked (or protected) and
released when the access is removed. This needs to be repeated by all the processes to secure data.
Signals − Signal is a mechanism to communication between multiple processes by way of signaling.
This means a source process will send a signal (recognized by number) and the destination process
will handle it accordingly.
Note − Almost all the programs in this tutorial are based on system calls under Linux Operating
System (executed in Ubuntu).
Page 41
MCET OPERATING SYSTEMS LAB MANUAL
OUTPUT:
$ vi echopipe.c
$ cc echopipe.c
$ ./a.out
RESULT:
Thus the program was executed and verified successfully.
#include<sys/ipc.h>
#include<stdio.h>
#include<string.h>
#include<sys/msg.h>
#include<stdlib.h> struct
{ long mtype; char
mtext[20]; }send,recv
; main()
{ int qid,pid,len;
qid=msgget((key_t)0X2000,IPC_CREAT|0666); if(qid==-
1)
{ perror("\n message failed");
exit(1); } send.mtype=1;
strcpy(send.mtext,"\n hello i am parent");
len=strlen(send.mtext); pid=fork();
if(pid>0)
{ if(msgsnd(qid,&send,len,0)==-1)
{ perror("\n message sending failed");
exit(1); } printf("\n message has been
posted"); sleep(2);
if(msgrcv(qid,&recv,100,2,0)==-1)
Page 43
MCET OPERATING SYSTEMS LAB MANUAL
OUTPUT:
$ vi echomsg.c
$ cc echomsg.c
$ ./a.out received from parent - hello i am
parent message has been posted message
received from child - hi i am child
RESULT:
Thus the program was executed and verified successfully.
readers-writers problem are two classical case studies considered to describe and test
synchronization mechanisms. These two problems are implemented in various simulation models,
each with a different solution or different workload parameters to study the process synchronization
mechanisms that can be used with interacting processes.
6.A) Dining Philosophers Problem.
AIM:To write C programs to simulate solutions to Dining Philosophers Problem.
DESCRIPTION:
The dining – philosophers problem is considered a classic synchronization problem because
it is an example of a large class of concurrency – control problems. It is a simple representation of
the need to allocate several resources among several processes in a deadlock-free and starvationfree
manner. Consider five philosophers who spend their lives thinking and eating. The philosophers
share a circular table surrounded by five chairs, each belonging to one philosopher. In the center of
the table is a bowl of rice, and the table is laid with five single chopsticks. When a philosopher
thinks, she does not interact with her colleagues. From time to time, a philosopher gets hungry and
tries to pick up the two chopsticks that are closest to her (the chopsticks that are between her and
her left and right neighbours). A philosopher may pick up only one chopstick at a time. Obviously,
she cam1ot pick up a chopstick that is already in the hand of a neighbour. When a hungry
philosopher has both her chopsticks at the same time, she eats without releasing her chopsticks.
When she is finished eating, she puts down both of her chopsticks and starts thinking again. The
dining-philosophers problem may lead to a deadlock situation and hence some rules have to be
framed to avoid the occurrence of deadlock.
ALGORITHM:
Step 1: Start the program.
Step 2: Define the number of philosophers.
Step 3: Declare one thread per philosopher.
Step 4: Declare one chopsticks per philosopher.
Step 5: When a philosopher is hungry.
i. See if chopsticks on both sides are free.
ii. Acquire both chopsticks or. iii. Eat. iv. restore the
chopsticks.
v. If chopsticks aren’t free.
Step 6: Wait till they are available.
Step 7: Stop the program.
PROGRAM:
SOURCE CODE:
Page 45
MCET OPERATING SYSTEMS LAB MANUAL
Page 46
MCET OPERATING SYSTEMS LAB MANUAL
}
} one()
{ int pos=0, x, i;
printf("\nAllow one philosopher to eat at any time\n"); for(i=0;i<howhung;
i++, pos++)
{ printf("\nP %d is granted to eat", philname[hu[pos]]);
for(x=pos;x<howhung;x++) printf("\nP %d is waiting",
philname[hu[x]]); } } two() {
Page 47
MCET OPERATING SYSTEMS LAB MANUAL
P 3 is granted to eat
P 3 is waiting
P 5 is waiting
P 0 is waiting
P 5 is granted to eat
P 5 is waiting
P 0 is waiting
P 0 is granted to eat
P 0 is waiting
1.One can eat at a time 2.Two can eat at a time 3.Exit
Enter your choice: 2
Allow two philosophers to eat at same time combination
1
P 3 and P 5 are granted to eat
P 0 is waiting combination 2
P 3 and P 0 are granted to eat
P 5 is waiting combination 3
P 5 and P 0 are granted to eat
P 3 is waiting
1.One can eat at a time 2.Two can eat at a time 3.Exit
Enter your choice: 3
RESULT:
Thus the program was executed and verified successfully.
consuming another item. The producer and consumer must be synchronized, so that the consumer
does not try to consume an item that has not yet been produced.
ALGORITHM:
Step 1: Start the program.
Step 2: Declare and initialize the necessary variables.
Step 3: Create a Producer.
Step 4: Producer (Child Process) performs a down operation and writes a message.
Step 5: Producer performs an up operation for the consumer to consume.
Step 6: Consumer (Parent Process) performs a down operation and reads or consumes the data
(message).
Step 7: Consumer then performs an up operation.
Step 8: Stop the program.
PROGRAM :
SOURCE CODE:
#include<stdio.h> void
main()
{ int buffer[10], bufsize, in, out, produce, consume, choice=0; in =
0; out = 0; bufsize = 10; while (choice !=3)
{ printf(“\n1. Produce \t 2. Consume \t3. Exit”);
printf(“\nEnter your choice: ”);
scanf(“%d”, &choice);
switch(choice)
{ case 1: if((in+1)%bufsize==out)
printf(“\nBuffer is Full”); else
{ printf(“\nEnter the value: “);
scanf(“%d”, &produce);
buffer[in] = produce; in =
(in+1)%bufsize;
} break; case 2: if(in == out)
printf(“\nBuffer is Empty”); else
{ consume = buffer[out];
printf(“\nThe consumed value is %d”, consume); out
= (out+1)%bufsize;
} break;
}
Page 49
MCET OPERATING SYSTEMS LAB MANUAL
}
}
OUTPUT:
Produce 2. Consume 3. Exit
Enter your choice: 2
Buffer is Empty
Produce 2. Consume 3. Exit
Enter your choice: 2
Enter the value: 100
Produce 2. Consume 3. Exit
Enter your choice: 1
The consumed values is 100
Produce 2. Consume 3. Exit
Enter your choice: 3
RESULT:
Thus the program was executed and verified successfully.
Step 6: Write performs a down operation and writes or access the data (message) from the database.
Step 7: Writer then performs an up operation.
Step 8: Stop the program.
PROGRAM:
SOURCE CODE:
//File: mesg.h
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<stdlib.h>
#define MKEY1 5543L
#define MKEY2 4354L
#define PERMS 0666 typedef
struct
{
long mtype;
char mdata[50]; }mesg;
//File: sender1.c
#include "mesg.h"
mesg msg; int
main()
{
int mq_id; int n; if((mq_id=msgget(MKEY1,PERMS|
IPC_CREAT))<0)
{
printf("Sender: Error creating message");
exit(1);
}
msg.mtype=1111L;
n=read(0,msg.mdata,50); msg.mdata[n]='\0';
msgsnd(mq_id,&msg,50,0);
}
Page 51
MCET OPERATING SYSTEMS LAB MANUAL
//File: receiver1.c
#include "mesg.h"
mesg msg; main()
{
int mq_id; int n;
if( ( mq_id=msgget(MKEY1, PERMS|IPC_CREAT ) ) < 0)
{
printf("receiver: Error opening message");
exit(1);
}
msgrcv(mq_id,&msg,50,1111L,0);
write(1,msg.mdata,50); msgctl(mq_id,IPC_RMID,NULL);
}
OUTPUT:
$ vi mesg.h
$ vi sender1.c
$ vi receiver1.c
$ cc sender1.c
$ ./a.out mcet $
cc receiver1.c
$ ./a.out mcet
RESULT:
Thus the program was executed and verified successfully.
Page 52
MCET OPERATING SYSTEMS LAB MANUAL
l[3],work[
3],flag,co
unt=0,seq
uence[10]
,k=0;
printf("\
nEnter the
number of
process:")
;
scanf("%d
",&n);
for(i=0;i<
n;i++)
{ printf("\nEnter the %dth process allocated resources:",i); scanf("%d%d
%d",&p[i].allocation[0],&p[i].allocation[1],&p[i].allocation[2]); printf("\
nEnter the %dth process maximum resources:",i); scanf("%d%d
%d",&p[i].max[0],&p[i].max[1],&p[i].max[2]); p[i].finish=0;
p[i].need[0]=p[i].max[0]-p[i].allocation[0]; p[i].need[1]=p[i].max[1]-
p[i].allocation[1]; p[i].need[2]=p[i].max[2]-p[i].allocation[2];
} printf("\nEnter the available vector:");
scanf("%d%d
%d",&avail[0],&avail[1],&avail[2]);
for(i=0;i<3;i++) work[i]=avail[i];
while(count!=n)
{ count=0;
for(i=0;i<n;i+
+)
{ flag=1; if(p[i].finish==0) if(p[i].need[0]<=work[0])
if(p[i].need[1]<=work[1])
if(p[i].need[2]<=work[2])
{ for(j=0;j<3;j++) work[j]
+=p[i].allocation[j];
p[i].finish=1;
sequence[k++]=i;
flag=0;
Page 54
MCET OPERATING SYSTEMS LAB MANUAL
}
if(flag==1) count++;
} } count=0;
for(i=0;i<n;i++)
if(p[i].finish==1)
count++;
printf("\n The safe sequence is:\t");
if(count++==n) for(i=0;i<k;i++)
printf("%d\n",sequence[i]);
else
printf("SYSTEM IS NOT IN A SAFE STATE \n\n");
return 0;
}
OUTPUT
$ vi bankersavoidance.c
$ cc bankersavoidance.c
$ ./a.out
Enter the number of process: 3
Enter the 0th process allocated resources: 1 2 3
Enter the 0th process maximum resources: 4 5 6
Enter the 1th process allocated resources: 3 4 5
Enter the 1th process maximum resources: 6 7 8
Enter the 2th process allocated resources: 1 2 3
Enter the 2th process maximum resources: 3 4 5
Enter the available vector: 10 12 11
The safe sequence is: 0 1 2
RESULT:
Thus the program was executed and verified successfully.
Page 55
MCET OPERATING SYSTEMS LAB MANUAL
ALGORITHM:
Step 1: Start the program
Step 2: Read the number of frames
Step 3: Read the number of pages
Step 4: Read the page numbers
Step 5: Initialize the values in frames to -1
Step 6: Allocate the pages in to frames in First in first out order.
Step 7: Display the number of page faults.
Step 8: Stop the program
PROGRAM:
SOURCE CODE:
Page 56
MCET OPERATING SYSTEMS LAB MANUAL
OUTPUT:
$ vi fifo.c
$ cc fifo.c
$ ./a.out
2 2-->F
3 23-->F
2 23
Page 57
MCET OPERATING SYSTEMS LAB MANUAL
1 231-->F
5 531-->F
2 521-->F
4 524-->F
5 524
3 324-->F
2 324
5 354-->F
2 352-->F
No of faults: 9
RESULT:
Thus the program was executed and verified successfully.
8.B) LRU
AIM:To Simulate LRU page replacement algorithms.
ALGORITHM:
Step 1: Start the program.
Step 2: Read the number of frames.
Step 3: Read the number of pages.
Step 4: Read the page numbers.
Step 5: Initialize the values in frames to -1.
Step 6: Allocate the pages in to frames by selecting the page that has not been used for the longest
period of time.
Step 7: Display the number of page faults.
Step 8: Stop the program.
PROGRAM :
SOURCE CODE:
/* A program to simulate LRU Page Replacement Algorithm */
#include<stdio.h> main()
{ int a[5],b[20],p=0,q=0,m=0,h,k,i,q1=1,j,u,n; char
f='F';
Page 58
MCET OPERATING SYSTEMS LAB MANUAL
{ q1=q;
} } printf("\
n%d",b[i]);
printf("\t");
for(h=0;h<q1;h++) printf("%d",a[h]);
if((p==0)&&(q<=3))
{ printf("-->%c",f); m+
+;
} p=0;
if(q1==3
)
{ for(k=0;k<q1;k++)
{ if(b[i+1]==a[k]) p=1;
} for(j=0;j<q1;j++)
{ u=0; k=i;
while(k>=(i-1)&&(k>=0))
{ if(b[k]==a[j]) u++;
k--;
} if(u==0)
q=j;
}
}
else
{ for(k=0;k<q;k++)
{
Page 59
MCET OPERATING SYSTEMS LAB MANUAL
if(b[i+1]==a[k]) p=1;
}
} } printf("\nNo of
faults:%d",m);
}
OUTPUT:
$ vi lru.c
$ cc lru.c
$ ./a.out
Enter the number of pages: 12 Enter
12 Page Numbers:
2 3 2 1 5 2 4 5 3 2 5 2
2 2-->F
3 23-->F
2 23
1 231-->F
5 251-->F
2 251
4 254-->F
5 254
3 354-->F
2 352-->F
5 352
2 352
No of faults: 7
RESULT:
Thus the program was executed and verified successfully.
Page 60
MCET OPERATING SYSTEMS LAB MANUAL
The simplest form of disk scheduling is, of course, the first-come, first-served (FCFS)
algorithm. This algorithm is intrinsically fair, but it generally does not provide the fastest service.
Consider, for example, a disk queue with requests for I/O to blocks on cylinders 98, 183, 37, 122,
14, 124, 65, 67. If the disk head is initially at cylinder 53, it will first move from 53 to 98, then to
183, 37, 122, 14, 124, 65, and finally to 67, for a total head movement of 640 cylinders.
ALGORITHM:
1. Let Request array represents an array storing indexes of tracks that have been requested in
ascending order of their time of arrival. ‘head’ is the position of disk head.
2. Let us one by one take the tracks in default order and calculate the absolute distance of the
track from the head.
3. Increment the total seek count with this distance.
4. Currently serviced track position now becomes the new head position.
5. Go to step 2 until all tracks in request array have not been serviced.
#include<stdio.h>
int main() {
int queue[20],n,head,i,j,k,seek=0,max,diff;
float avg;
printf("Enter the max range of disk\n");
scanf("%d",&max);
printf("Enter the size of queue request\n");
scanf("%d",&n);
printf("Enter the queue of disk positions to be read\n");
for(i=1;i<=n;i++) scanf("%d",&queue[i]);
printf("Enter the initial head position\n");
scanf("%d",&head); queue[0]=head;
for(j=0;j<=n-1;j++)
{
diff=abs(queue[j+1]-queue[j]);
seek+=diff;
printf("Disk head moves from %d to %d with
seek %d\n",queue[j],queue[j+1],diff);
}
printf("Total seek time is %d\n",seek);
avg=seek/(float)n;
printf("Average seek time is %f\n",avg);
return 0;
}
OUTPUT
Enter the max range of disk
200
Page 61
MCET OPERATING SYSTEMS LAB MANUAL
RESULT:
SSTF stands for Shortest Time First which very uses full of learning about how the disk drive
manages the data having the shortest seek time.
ALGORITHM :
1. Let Request array represents an array storing indexes of tracks that have been requested.
‘head’ is the position of disk head.
Page 62
MCET OPERATING SYSTEMS LAB MANUAL
2. Find the positive distance of all tracks in the request array from head.
3. Find a track from requested array which has not been accessed/serviced yet and has
minimum distance from head.
4. Increment the total seek count with this distance.
5. Currently serviced track position now becomes the new head position.
6. Go to step 2 until all tracks in request array have not been serviced.
#include<stdio.h>
#include<conio.h> #include<math.h> int
main() { int
queue[100],t[100],head,seek=0,n,i,j,temp;
float avg; // clrscr();
printf("*** SSTF Disk Scheduling Algorithm ***\n");
printf("Enter the size of Queue\t"); scanf("%d",&n);
printf("Enter the Queue\t"); for(i=0;i<n;i++)
{
scanf("%d",&queue[i]);
} printf("Enter the initial head position\
t"); scanf("%d",&head); for(i=1;i<n;i++)
t[i]=abs(head-queue[i]); for(i=0;i<n;i++)
{ for(j=i+1;j<n;j++)
{ if(t[i]>t[j])
{ temp=t[i];
t[i]=t[j];
t[j]=temp;
temp=queue[i];
queue[i]=queue[j];
queue[j]=temp;
}
} } for(i=1;i<n-
1;i++)
{ seek=seek+abs(head-queue[i]);
head=queue[i];
Page 63
MCET OPERATING SYSTEMS LAB MANUAL
OUTPUT:
RESULT:
Page 64