OS LAB file

Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

IMS ENGINEERING COLLEGE

OPERATING SYSTEM LAB FILE


(BCS-451)

B.TECH – II YEAR
(EVEN SEM 2023-2024)

Name

Roll No.

Section-Batch

DEPARTMENT OF COMPUTER SCIENCE

IMS ENGINEERING COLLEGE


(Affiliated to Dr A PJ Abdul Kalam Technical University, Lucknow )
Approved by AICTE - Accredited by NAAC – ‘A’
GradeNH#24, AdhyatmikNagar, Ghaziabad,UP,India
www.imsec.ac.in
INDEX
Subject: Operating System Lab Code:BCS-451

S.NO. NAME OF EXPERIMENT DATE OF FACULTY


SUBMISSION SIGNATURE
1 Study of hardware and software requirements of different
operating systems (UNIX, LINUX,WINDOWS XP,
WINDOWS7/8
2 Execute various UNIX system calls for
i. Process management
ii. File management
iii. Input/output Systems calls
3 Implement CPU Scheduling Policies:
i. SJF
ii. Priority
iii. FCFS Multi-level Queue
4 Implement file storage allocation technique:
i. Contiguous (using array)
ii. Linked –list (using linked-list)
iii. Indirect allocation (indexing)
5 Implementation of contiguous allocation techniques:
i. Worst-Fit
ii. First -Fit
iii. Best-Fit
6 Calculation of external and internal fragmentation
i. Free space list of blocks from system
ii. List process file from the system

7 Implementation of compaction for the continually


changing memory
layout and calculate total movement of data.
8 Implementation of resource allocation graph (RAG)

9 Implementation of Banker’s algorithm.

10 Conversion of resource allocation graph (RAG) to wait


for graph
(WFG) for each type of method used for storing graph.

2
11 Implement the solution for Bounded Buffer (producer-
consumer) problem using inter process communication
techniques-Semaphores.
12 Implement the solutions for Readers-Writer’s
problem using inter process communication technique
–Semaphore.

3
EXPERIMENT NO. -1

AIM: Study of hardware and software requirements of different


operating systems (UNIX, LINUX, WINDOWS XP, WINDOWS7/8).

Procedure:

various software and hardware requirements for different Operating System are as
follow:

1) MSDOS
• AT compatible CPU with 386 or greater processor
• 16 MB of RAM
• 1.44 Mb floppy diskette drive or CD-ROM drive
• EGA 640x480 or better screen resolution
• Bootable Floppy or CD-ROM disk containing DOS, or start up disk for
Windows 95/98.
• Source HDD/SSD of type IDE/SATA/SCSI attached
• Destination FAT/FAT32 volume that may be local or mapped network
drive for storing images

2) LINUX
• Processor 64-bit, EM64T
• RAM 1 GB or greater
• Swap space 1 GB or greater
• Disk space 500 MB free space

3) UNIX
• Random Access Memory (RAM)
• 256MB recommended
• 128MB minimum
• 250MB available hard drive space (see note)
• CD-ROM drive
• TCP/IP network interface

4) Windows 98
• 486DX 66 MHz or better processor (Pentium recommended)
• 16 megabytes (MB) of memory (24 MB recommended)
• 120 MB minimum of free hard-disk space (Note that typical installation
requires approximately 195 MB of free hard-disk space, but may range
between 120 MB to 295 MB, depending
• CD-ROM or DVD-ROM drive

4
• 3.5-inch high-density floppy disk drive
• Display adapter and monitor that support VGA or higher resolution
• Microsoft Mouse or compatible pointing device.

5) Windows XP
• Pentium 233-megahertz (MHz) processor or faster (300 MHz is
recommended)
• At least 64 megabytes (MB) of RAM (128 MB is recommended)
• At least 1.5 gigabytes (GB) of available space on the hard disk
• CD-ROM or DVD-ROM drive
• Video adapter and monitor with Super VGA (800 x 600) or higher
resolution

6) Windows 2000
• 133MHz or higher Pentium-compatible CPU
• 64MB RAM recommended minimum (4GB RAM maximum)
• 2GB hard disk with a minimum of 650MB of free space. Additional free
hard disk space is required if you are installing over a network.
• Pentium II or better
• At least 128MB of RAM
• 4GB hard drive, with at least 1GB free

7) Windows 8
• CPU SPEED: 1 GHz or faster processor
• RAM: 1 GB RAM (32-bit) or 2 GB RAM (64-bit)
• VIDEO CARD: DirectX 9 graphics with WDDM 1.0 driver
• PIXEL SHADER: 2.0
• FREE DISK SPACE: 16GB space(32-bit) or 20 GB(64-bit)

8) Windows 10
• Processor: 1 gigahertz (GHz) or faster processor
• RAM: 1 gigabyte (GB) for 32-bit or 2 GB for 64-bit
• Hard disk space: 16 GB for 32-bit OS or 20 GB for 64-bit OS
• Graphics card: DirectX 9 or later with WDDM 1.0 driver
• Display: 800 x 600

Viva Questions:
1. What is Operating System?
2. Differentiate multiprogramming and multitasking.
3. What is kernel?
4. Name any 2 Open-source operating system.
5. What is multi-Threading?

5
EXPERIMENT NO. -2

AIM: Execute various UNIX system calls for


i. Process management
ii. File management
iii. Input/output Systems calls

Procedure:

Basic commands used for process management and file management in Linux/Unix
are as follow:

Process Management:

1) top:
The top (table of processes) command shows a real-time view of running processes in
Linux and displays kernel-managed tasks. The command also provides a system
information summary that shows resource utilization, including CPU and memory usage.

2) ps:
The ps (processes status) command is a native Unix/Linux utility for viewing information
concerning a selection of running processes on a system: it reads this information from
the virtual files in the /proc filesystem.

3) sleep:
The sleep command suspends the calling process of the next command for a specified
amount of time. This property is useful when the following command's execution depends
on the successful completion of a previous command.

4) jobs:
Jobs command is used to list the jobs that you are running in the background and in
the foreground. If the prompt is returned with no information no jobs are present. All
shells are not capable of running this command.

5) kill:
The command kill sends the specified signal to the specified processes. If no signal is
specified, the TERM signal is sent. The default action for this signal is to terminate
the process.

File Management:

1) ls:
The ls command is used to list files. "ls" on its own lists all files in the current
directory except for hidden files.

6
2) ls- s:
The ls- s will list all files sizes.

3) ls- a:
The ls- a will list all files including hidden files (files with names beginning with a
dot).

4) mkdir:
The mkdir command in Linux/Unix allows users to create or make new directories. mkdir
stands for “make directory.” With mkdir , you can also set permissions, create multiple
directories (folders) at once.

5) vi:
The vi command is an interactive text editor that is display-oriented: the screen of
your terminal acts as a window into the file you are editing. Changes you make to the file
are reflected in what you see. Using vi you can insert text anywhere in the file very
easily. Most of the vi commands move the cursor around in the file.

6) cat:
The cat command is a utility command in Linux. One of its most commonly known usages
is to print the content of a file onto the standard output stream. Other than that, the cat
command also allows us to write some texts into a file.

7) mv:
The mv command moves files and directories from one directory to another or
renames a file or directory. If you move a file or directory to a new directory, it
retains the base file name. When you move a file, all links to other files remain intact,
except when you move it to a different file system.

8) cv:
The cp command to create a copy of the contents of the file or directory specified by
the Source File or Source Directory parameters into the file or directory specified by
the Target File or Target Directory parameters.

9) rm:
The rm stands for remove here. rm command is used to remove objects such as files,
directories, symbolic links and so on from the file system like UNIX. To be more precise,
rm removes references to objects from the filesystem, where those objects might have
had multiple references (for example, a file with two different names). By default, it does
not remove directories.

10) rmdir:
The rmdir command removes the directory, specified by the Directory parameter,
from the system. The directory must be empty before you can remove it, and you
must have written permission in its parent directory. Use the ls -al command to check
whether the directory is empty.

7
System Calls:

Command & Output:


Process Management:

8
File Management:

9
Viva Questions:
1. Define various states of process life cycle.
2. Explain various functions of Operating System.
3. What are system calls?
4. What are interrupts?
5. Explain Linux and Unix

10
EXPERIMENT NO. -3

AIM: Implement CPU Scheduling Policies:


i. FCFS
ii. SJF
iii. Priority

i. First Come First Serve (FCFS)

Procedure:

To calculate the average waiting time using the FCFS algorithm first the waiting time
of the first process is kept zero and the waiting time of the second process is the burst
time of the first process and the waiting time of the third process is the sum of the
burst times of the first and the second process and so on. After calculating all the
waiting times the average waiting time is calculated as the average of all the waiting
times. FCFS mainly says first come first serve the algorithm which came first will be
served first.

ALGORITHM:

Step 1: Start the process


Step 2: Accept the number of processes in the ready Queue
Step 3: For each process in the ready Q, assign the process name and the burst
time Step 4: Set the waiting of the first process as ‗0‘and its burst time as its
turnaround time Step 5: for each process in the Ready Q calculate
a). Waiting time (n) = waiting time (n-1) + Burst time (n-1) b). Turnaround time (n)=
waiting time(n)+Burst time(n)
Step 6: Calculate
a) Average waiting time = Total waiting Time / Number of process

b) Average Turnaround time = Total Turnaround Time / Number of process Step 7:


Stop the process

Code/Method:

#include<stdio.h> #include<conio.h>
main()
{
int bt[20], wt[20], tat[20], i, n; float wtavg, tatavg;
clrscr();
printf("\nEnter the number of processes -- ");
scanf("%d", &n);

11
for(i=0;i<n;i++)
{
printf("\nEnter Burst Time for Process %d -- ", i); scanf("%d", &bt[i]);
}
wt[0] = wtavg = 0; tat[0] = tatavg = bt[0]; for(i=1;i<n;i++)
{
wt[i] = wt[i-1] +bt[i-1];
tat[i] = tat[i-1] +bt[i]; wtavg = wtavg + wt[i]; tatavg = tatavg + tat[i];
}
printf("\t PROCESS \tBURST TIME \t WAITING TIME\t TURNAROUND
TIME\n");
for(i=0;i<n;i++)
printf("\n\t P%d \t\t %d \t\t %d \t\t %d", i, bt[i], wt[i], tat[i]); printf("\nAverage
Waiting Time -- %f", wtavg/n);
printf("\nAverage Turnaround Time -- %f", tatavg/n); getch();
}

Input:

Enter the number of processes -- 3


Enter Burst Time for Process 0 -- 24
Enter Burst Time for Process 1 -- 3
Enter Burst Time for Process 2 -- 3

Output:

PROCESS BURSTTIME WAITING TIME TURNAROUND


TIME
P0 24 0 24
P1 3 24 27
P2 3 27 30
AverageWaitingTime-- 17.000000
Average Turnaround Time -- 27.000000

12
ii. SHORTEST JOB FIRST

Procedure:
To calculate the average waiting time in the shortest job first algorithm the sorting of the
process based on their burst time in ascending order then calculate the waiting time
of each process as the sum of the bursting times of all the process previous or before to
that process.

ALGORITHM:

Step 1: Start the process


Step 2: Accept the number of processes in the ready Queue
Step 3: For each process in the ready Q, assign the process id and accept
the CPU burst time
Step 4: Start the Ready Q according the shortest Burst time by sorting
according to lowest to highest burst time.
Step 5: Set the waiting time of the first process as ‗0‘and its turnaround
time as its burst time.
Step 6: Sort the processes names based on their Burt time Step 7: For each
process the ready queue, calculate
Waiting time(n)= waiting time (n-1) + Burst time (n-1)
Turnaround time (n)= waiting time(n)+Burst time(n)
Step 8: Calculate
Average waiting time = Total waiting Time / Number of process
Average Turnaround time = Total Turnaround Time / Number of process
Step 9: Stop the process

Code/Method:

#include<stdio.h> #include<conio.h>
main()
{
int p[20], bt[20], wt[20], tat[20], i, k, n, temp; float wtavg, tatavg;
clrscr();
printf("\nEnter the number of processes -- "); scanf("%d", &n);
for(i=0;i<n;i++)
{
p[i]=i;
printf("Enter Burst Time for Process %d -- ", i); scanf("%d", &bt[i]);

}
for(i=0;i<n;i++) for(k=i+1;k<n;k++) if(bt[i]>bt[k])
{

13
temp=bt[i]; bt[i]=bt[k]; bt[k]=temp;

temp=p[i]; p[i]=p[k]; p[k]=temp;


}
wt[0] = wtavg = 0;
tat[0] = tatavg = bt[0]; for(i=1;i<n;i++)
{
wt[i] = wt[i-1] +bt[i-1];
tat[i] = tat[i-1] +bt[i]; wtavg = wtavg + wt[i]; tatavg = tatavg + tat[i];
}
printf("\n\t PROCESS \tBURST TIME \t WAITING TIME\t
TURNAROUND TIME\n");
for(i=0;i<n;i++)
printf("\n\t P%d \t\t %d \t\t %d \t\t %d", p[i], bt[i], wt[i], tat[i]);
printf("\nAverage Waiting Time -- %f", wtavg/n);
printf("\nAverage Turnaround Time -- %f", tatavg/n); getch();}

Input:
Enter the number of processes --
4
Enter Burst Time for Process 0 -- 6
Enter Burst Time for Process 1 -- 8
Enter Burst Time for Process 2 -- 7
Enter Burst Time for Process 3 -- 3

Output:

, PROCESS BURST WAITING TURNAROUND


TIME TIME TIME
P3 3 0 3
P0 6 3 9
P2 7 9 16
P1 8 16 24
Average Waiting Time -- 7.000000
Average Turnaround Time -- 13.000000

14
iii. PRIORITY

DESCRIPTION:

To calculate the average waiting time in the priority algorithm, sort the burst times
according to their priorities and then calculate the average waiting time of the
processes. The waiting time of each process is obtained by summing up the burst times
of all the previous processes.

ALGORITHM:

Step 1: Start the process


Step 2: Accept the number of processes in the ready Queue
Step 3: For each process in the ready Q, assign the process id and accept the CPU
burst time
Step 4: Sort the ready queue according to the priority number.
Step 5: Set the waiting of the first process as ‗0‘ and its burst time as its
turnaround time Step 6: Arrange the processes based on process priority
Step 7: For each process in the Ready Q calculate Step 8:
for each process in the Ready Q calculate
a) Waiting time(n)= waiting time (n-1) + Burst time (n-1)
b) Turnaround time (n)= waiting time(n)+Burst time(n)
Step 9: Calculate
c) Average waiting time = Total waiting Time / Number of process
d) Average Turnaround time = Total Turnaround Time / Number of process Print
the results in an order.
Step10: Stop

SOURCE CODE:
#include<stdio.h> main()
{
int p[20],bt[20],pri[20], wt[20],tat[20],i, k, n, temp; float wtavg, tatavg;
clrscr();
printf("Enter the number of processes --- "); scanf("%d",&n);
for(i=0;i<n;i++){ p[i] = i;
printf("Enter the Burst Time & Priority of Process %d --- ",i); scanf("%d
%d",&bt[i], &pri[i]);
}
for(i=0;i<n;i++) for(k=i+1;k<n;k++) if(pri[i] > pri[k]){ temp=p[i]; p[i]=p[k];
p[k]=temp; temp=bt[i]; bt[i]=bt[k]; bt[k]=temp; temp=pri[i]; pri[i]=pri[k];
pri[k]=temp;
}
wtavg = wt[0] = 0; tatavg = tat[0] = bt[0]; for(i=1;i<n;i++)
{

15
wt[i] = wt[i-1] + bt[i-1];
tat[i] = tat[i-1] + bt[i];

wtavg = wtavg + wt[i]; tatavg = tatavg + tat[i];


}
printf("\nPROCESS\t\tPRIORITY\tBURST TIME\tWAITING
TIME\tTURNAROUND TIME");
for(i=0;i<n;i++)
printf("\n%d \t\t %d \t\t %d \t\t %d \t\t %d ",p[i],pri[i],bt[i],wt[i],tat[i]);
printf("\nAverage Waiting Time is --- %f",wtavg/n); printf("\nAverage Turnaround
Time is --- %f",tatavg/n);
getch();}

INPUT
Enter the number of processes -- 5
Enter the Burst Time & Priority of Process 0 --- 10
3
Enter the Burst Time & Priority of Process 1 --- 1 1
Enter the Burst Time & Priority of Process 2 --- 2 4
Enter the Burst Time & Priority of Process 3 --- 1 5
Enter the Burst Time & Priority of Process 4 --- 5 2
OUTPUT
PROCESS PRIORITY BURST TIMEWAITING TIMETURNAROUND
TIME
1 1 1 0 1
4 2 5 1 6
0 3 10 6 16
2 4 2 16 18
3 5 1 18 19
Average Waiting Time is --- 8.200000
Average Turnaround Time is 12.000000
Viva Questions:
1) Define the following
a)Turnaround time b) Waiting time c) Burst time d) Arrival time
2) What is meant by process scheduling?
3) What are the various states of process?
4) What is the difference between pre-emptive and non-pre-emptive scheduling
5) What is meant by time slice?

16
EXPERIMENT NO. - 4

AIM: Implement file storage allocation technique:


i. Contiguous(using array)
ii. Linked –list(using linked-list)
iii. Indirect allocation (indexing)

i) SEQUENTIAL:

Procedure:
The most common form of file structure is the sequential file in this type of file, a
fixed format is used for records. All records (of the system) have the same length,
consisting of the same number of fixed length fields in a particular order because the
length and position of each field are known, only the values of fields need to be
stored, the field name and length for each field are attributes of the file structure.

ALGORITHM:
Step 1: Start the program.
Step 2: Get the number of files.
Step 3: Get the memory requirement of each file.
Step 4: Allocate the required locations to each in sequential order a). Randomly select
a location from availablelocation s1= random(100);
a) Check whether the required locations are free from the selected
location.
if(b[s1].flag==0){
for (j=s1;j<s1+p[i];j++){ if((b[j].flag)==0)count++;
}
if(count==p[i]) break;
}
b) Allocate and set flag=1 to the allocated locations.
for(s=s1;s<(s1+p[i]);s++)
{
k[i][j]=s; j=j+1; b[s].bno=s; b[s].flag=1;
}
Step 5: Print the results file no, length, Blocks allocated. Step 6: Stop the program

Code/Method:

#include<stdio.h>
main()
{

17
int f[50],i,st,j,len,c,k; clrscr(); for(i=0;i<50;i++) f[i]=0;
printf("\n Enter the starting block & length of file");
scanf("%d%d",&st,&len);
for(j=st;j<(st+len);j++) if(f[j]==0)
{
f[j]=1
;
printf("\n%d->%d",j,f[j]);
}
else
{
printf("Block already allocated"); break;
}
if(j==(st+len))
printf("\n the file is allocated to disk");
printf("\n if u want to enter more files?(y-1/n-0)"); scanf("%d",&c);
if(c==1) goto X; else exit();
getch();
}

OUTPUT:
Enter the starting block & length of file 4 10 4->1
5->1
6->1
7->1
8->1
9->1
10->1
11->1
12->1
13->1
The file is allocated to disk.

ii) INDEXED:

Procedure:
In the chained method file allocation table contains a field which points to starting block
of memory. From it for each bloc a pointer is kept to next successive block. Hence, there
is no external fragmentation.

ALGORITHM:

Step 1: Start the program.


Step 2: Get the number of files.

18
Step 3: Get the memory requirement of each file.
Step 4: Allocate the required locations by selecting a location randomly q=
random(100);
a) Check whether the selected location is free .
b) If the location is free allocate and set flag=1 to the allocated locations.

q=random(100);
{
if(b[q].flag==0)
b[q].flag=1;
b[q].fno=j;
r[i][j]=q;
Step 5: Print the results file no, length ,Blocks allocated.
Step 6: Stop the program

Code/Method:

#include<stdio.h>
Intf[50],i,k,j,inde[50],n,c,count=0,p;
main()
{
clrscr();
for(i=0;i<50;i++) f[i]=0;
x: printf("enter index block\t");
scanf("%d",&p);
if(f[p]==0)
{ f[p]=1;
printf("enter no of files on index\t");
scanf("%d",&n);
}
else
{
printf("Block already allocated\n");
goto x;
}
for(i=0;i<n;i++)
scanf("%d",&inde[i]);
for(i=0;i<n;i++)
if(f[inde[i]]==1)
{
printf("Block already allocated");
goto x;
}
for(j=0;j<n;j++) f[inde[j]]=1;

19
printf("\n allocated");
printf("\n file indexed");
for(k=0;k<n;k++)
printf("\n %d->%d:%d",p,inde[k],f[inde[k]]);
printf(" Enter 1 to enter more files and 0 to exit\t");
scanf("%d",&c);
if(c==1) goto x;
else exit();
getch();
}

OUTPUT: enter index block 9 Enter no of files on index 3 1 2 3


Allocated File indexed 9->1:1
9->2;1
9->3:1 enter 1 to enter more files and 0 to exit

iii) LINKED:

Procedure:
In the chained method file allocation table contains a field which points to starting block
of memory. From it for each bloc a pointer is kept to next successive block. Hence, there
is no external fragmentation

ALGORTHIM:
Step 1: Start the program. Step 2: Get the number of files.
Step 3: Get the memory requirement of each file.
Step 4: Allocate the required locations by selecting a location randomly q=
random(100);
a) Check whether the selected location is free .
b) If the location is free allocate and set flag=1 to the allocated locations.
While allocating next location address to attach it to previous location

for(i=0;i<n;i++)
{
for(j=0;j<s[i];j++)
{
q=random(100); if(b[q].flag==0) b[q].flag=1;
b[q].fno=j;
r[i][j]=q;
if(j>0)
{
}
}
p=r[i][j-1]; b[p].next=q;}

20
Step 5: Print the results file no, length ,Blocks allocated.
Step 6: Stop the program

Code/Method:
#include<stdio.h>
main()
{
int f[50],p,i,j,k,a,st,len,n,c;
clrscr();
for(i=0;i<50;i++)
f[i]=0;
printf("Enter how many blocks that are already allocated");
scanf("%d",&p);
printf("\nEnter the blocks no.s that are already allocated");
for(i=0;i<p;i++)
{
scanf("%d",&a);
f[a]=1;
}
X:
printf("Enter the startingindex block & length");
scanf("%d%d",&st,&len);
k=len;
for(j=st;j<(k+st);j++)
{
if(f[j]==0)
{ f[j]=1;
printf("\n%d->%d",j,f[j]);
}
else
{
printf("\n %d->file is already allocated",j);
k++;
}
}
printf("\n If u want to enter one more file? (yes-1/no-0)");
scanf("%d",&c); if(c==1)
goto X;
else exit();
getch( );}

OUTPUT:

21
Enter how many blocks that are already allocated 3 Enter the blocks no.s that are
already allocated 4 7 Enter the starting index block & length 3 7 9
3->1
4->1 file is already allocated 5->1
6->1
7->1 file is already allocated 8->1
9->1file is already allocated 10->1
11->1
12->1

Viva Questions:
1. List Various Types of Files.
2. What are various file allocation strategies?
3. What is linked allocation?
4. What are advantages of Linked allocation?
5. What are disadvantages of sequential allocation?

22
EXPERIMENT NO. - 5

AIM: Implementation of contiguous allocation techniques:


i. Worst-Fit
ii. Best- Fit
iii. First- Fit

Procedure:
One of the simplest methods for memory allocation is to divide memory into several fixed-
sized partitions. Each partition may contain exactly one process. In this multiple-
partition method, when a partition is free, a process is selected from the input queue and
is loaded into the free partition. When the process terminates, the partition becomes
available for another process. The operating system keeps a table indicating which parts
of memory are available and which are occupied. Finally, when a process arrives and
needs memory, a memory section large enough for this process is provided. When it
is time to load or swap a process into main memory, and if there is more than one free
block of memory of sufficient size, then the operating system must decide which free
block to allocate. Best-fit strategy chooses the block that is closest in size to the request.
First-fit chooses the first available block that is large enough. Worst-fit chooses the largest
available block.

i) WORST-FIT

Code/Method:
#include<stdio.h>
#include<conio.h>
#define max 25
void main()
{
int frag[max],b[max],f[max],i,j,nb,nf,temp; static int bf[max],ff[max];
clrscr();
printf("\n\tMemory Management Scheme - First Fit");
printf("\nEnter the number of blocks:");
scanf("%d",&nb);
printf("Enter the number of files:");
scanf("%d",&nf);
printf("\nEnterthe size of the blocks:-\n");
for(i=1;i<=nb;i++)
{
printf("Block %d:",i);
scanf("%d",&b[i]);
}

23
printf("Enter the size of the files :-\n"); for(i=1;i<=nf;i++)
{
printf("File %d:",i);
scanf("%d",&f[i]);

}
for(i=1;i<=nf;i++)
{
for(j=1;j<=nb;j++)
{
if(bf[j]!=1)
{
temp=b[j]-f[i]; if(temp>=0)
{
ff[i]=j; break;
}
}
}
frag[i]=temp; bf[ff[i]]=1;
}

}
printf("\nFile_no:\tFile_size :\tBlock_no:\tBlock_size:\tFragement");
for(i=1;i<=nf;i++)
printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d",i,f[i],ff[i],b[ff[i]],frag[i]);
getch();

INPUT
Enter the number of blocks: 3 Enter the number of files: 2
Enter the size of the blocks:- Block 1: 5
Block 2: 2
Block 3: 7

Enter the size of the files:- File 1: 1


File 2: 4

OUTPUT
File No File Size Block No Block Size Fragment
1 1 1 5 4
2 4 3 7 3

ii) BEST-FIT

24
#include<stdio.h> #include<conio.h>
#define max 25
void main()
{
int frag[max],b[max],f[max],i,j,nb,nf,temp,lowest=10000; static int bf[max],ff[max];
clrscr();
printf("\nEnter the number of blocks:");
scanf("%d",&nb);
printf("Enter the number of files:");
scanf("%d",&nf);
printf("\nEnter the size of the blocks:-\n");
for(i=1;i<=nb;i++)
printf("Block %d:",i);
scanf("%d",&b[i]);
printf("Enter the size of the files :-\n");
for(i=1;i<=nf;i++)
{
printf("File %d:",i);
scanf("%d",&f[i]);
}
for(i=1;i<=nf;i++)
{
for(j=1;j<=nb;j++)
{
if(bf[j]!=1)
{
temp=b[j]-f[i]; if(temp>=0)
if(lowest>temp)
{
ff[i]=j; lowest=temp;
}
}}
frag[i]=lowest; bf[ff[i]]=1; lowest=10000;
}
printf("\nFile No\tFile Size \tBlockNo\tBlock Size\tFragment");
for(i=1;i<=nf && ff[i]!=0;i++)

printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d",i,f[i],ff[i],b[ff[i]],frag[i]); getch();
}

INPUT
Enter the number of blocks: 3
Enter the number of files: 2
Enter the size of the blocks:- Block 1: 5

25
Block 2: 2
Block 3: 7
Enter the size of the files:- File 1: 1
File 2: 4

OUTPUT
File No File Size Block No
Block Size
Fragment
1 1 2 2 1
2 4 1 5 1

iii) FIRST-FIT
#include<stdio.h>
#include<conio.h>
#define max 25
void main()
{
int frag[max],b[max],f[max],i,j,nb,nf,temp,highes t=0; static int bf[max],ff[max];
clrscr();
printf("\n\tMemory Management Scheme - Worst Fit");
printf("\nEnter the number of blocks:");
scanf("%d",&nb);
printf("Enter the number of files:"); scanf("%d",&nf);
printf("\nEnter the size of the blocks:-\n");
for(i=1;i<=nb;i++)
{
printf("Block %d:",i);
scanf("%d",&b[i]);
}
printf("Enter the size of the files :-\n"); for(i=1;i<=nf;i++)
{
printf("File %d:",i);
scanf("%d",&f[i]);
}

for(i=1;i<=nf;i++)
{
for(j=1;j<=nb;j++)
{
if(bf[j]!=1) //if bf[j] is not allocated
{
temp=b[j]-f[i]; if(temp>=0)
26
if(highest<temp)
{
}
}
frag[i]=highest; bf[ff[i]]=1; highest=0;
}
ff[i]=j; highest=temp;
}
printf("\nFile_no:\tFile_size:\tBlock_no:\tBlock_size:\tFragement");
for(i=1;i<=nf;i++)
printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d",i,f[i],ff[i],b[ff[i]],frag[i]); getch();
}

INPUT
Enter the number of blocks: 3 Enter the
number of files: 2

Enter the size of the blocks:-

Block 1:5
Block 2:2
Block 3:7

Enter the size of the files:-


OUTPUT

FileNo FileSize BlockNo


Block Size Fragment
1 1 3 7 6
2 4 1 5 1

Viva Questions
1) What is virtual memory?
2) Define context switching.
3) What is fragmentation? Different types of fragmentation.
4) Explain Demand paging.
5) Explain best fit and worst fit.

27
EXPERIMENT NO. - 6

AIM: Calculation of external and internal fragmentation


i. Free space list of blocks from system
ii. List process file from the system

Procedure:
After implementing each allocation algorithm, list the amount of free space blocks left
out after performing allocation. When a block which is not at all allocated to any process
or file, it adds to external fragmentation. When a file or process is allocated the free
block and still some part of it is left unused, we count such unused portion into
internal fragmentation.

Code/Method:
#include<stdio.h>
#include<conio.h>
main()
{
int ms,mp[10],i,
temp,n=0; char ch = 'y';
clrscr();
printf("\nEnter the total memory available (in Bytes)-- ");
scanf("%d",&ms);
temp=ms;
for(i=0;ch=='y';i++,n++)
{
printf("\nEnter memory required for process %d (in Bytes) -- ",i+1);
scanf("%d",&mp[i]);
if(mp[i]<=temp)
{
printf("\nMemory is allocated for Process %d ",i+1);
temp = temp - mp[i];
}
else
{
printf("\nMemory is Full"); break;
}
printf("\nDo you want to continue(y/n) -- ");
scanf(" %c", &ch);
}

28
printf("\n\nTotal Memory Available -- %d", ms);
printf("\n\n\tPROCESS\t\t MEMORY ALLOCATED ");
for(i=0;i<n;i++)
printf("\n \t%d\t\t%d",i+1,mp[i]);
printf("\n\nTotal Memory Allocated is %d",ms-temp);
printf("\nTotal External Fragmentation is %d",temp);
getch();
}

Output:
Enter the total memory available (in Bytes) – 1000
Enter memory required for process 1 (in Bytes) –
400 Memory is allocated for Process 1
Do you want to continue(y/n) -- y
Enter memory required for process 2 (in Bytes) --
275 Memory is allocated for Process 2
Do you want to continue(y/n) – y
Enter memory required for process 3 (in Bytes) –
550 Memory is Full
Total Memory Available – 1000
PROCESS MEMORY ALLOCATED
1 400
2 275
Total Memory Allocated is 675
Total External Fragmentation is 325

Code/Method:
#include<stdio.h>
#include<conio.h>
main()
{
int ms,mp[10],i,
temp,n=0; char ch = 'y';
clrscr();
printf("\nEnter the total memory available (in
Bytes)-- ");
scanf("%d",&ms);
temp=ms;
for(i=0;ch=='y';i++,n++)
{
printf("\nEnter memory required for process %d (in
Bytes) -- ",i+1);

29
scanf("%d",&mp[i]);
if(mp[i]<=temp)
{
printf("\nMemory is allocated for Process %d
",i+1);
temp = temp - mp[i];
}
else
{
printf("\nMemory is Full"); break;
}
printf("\nDo you want to continue(y/n) -- ");
scanf(" %c", &ch);
}
printf("\n\nTotal Memory Available -- %d", ms);
printf("\n\n\tPROCESS\t\t MEMORY
ALLOCATED ");
for(i=0;i<n;i++)
printf("\n \t%d\t\t%d",i+1,mp[i]);
printf("\n\nTotal Memory Allocated is %d",ms-
temp);
printf("\nTotal External Fragmentation is
%d",temp);
getch();
}

Enter the total memory available (in Bytes) – 1000


Enter memory required for process 1 (in Bytes) –
400 Memory is allocated for Process 1
Do you want to continue(y/n) -- y
Enter memory required for process 2 (in Bytes) --
275 Memory is allocated for Process 2
Do you want to continue(y/n) – y
Enter memory required for process 3 (in Bytes) –
550 Memory is Full
Total Memory Available – 1000
PROCESS MEMORY ALLOCATED
1 400
2 275
Total Memory Allocated is 675
Total External Fragmentation is 325

30
Viva Questions
1) What is fragmentation?
2) Differentiate between internal and external fragmentation.
3) External fragmentation will not occur when?
4) External fragmentation exists when?
5) How fragmentation works on operating system?

31
EXPERIMENT NO. - 7

AIM: Implementation of compaction for the continually changing


memory layout and calculate total movement of data.

Procedure:
Compaction is a technique to collect all the free memory present in form of fragments into
one large chunk of free memory, which can be used to run other processes.It does that by
moving all the processes towards one end of the memory and all the available free space
towards the other end of the memory so that it becomes contiguous.It is not always easy
to do compaction. Compaction can be done only when the relocation is dynamic and done
at execution time. Compaction cannot be done when relocation is static and is performed
at load time or assembly time.

Code/Method:

#include<stdio.h>

#include<conio.h>

void create(int,int);

void del(int);

void compaction();

void display();

int fname[10],fsize[10],fstart[10],freest[10],freesize[10],m=0,n=0,start;

int main()

int name,size,ch,i;

int *ptr;

// clrscr();

ptr=(int *)malloc(sizeof(int)*100);

start=freest[0]=(int)ptr;

freesize[0]=500;

32
printf("\n\n");

printf(" Free start address Free Size \n\n");

for(i=0;i<=m;i++)

printf(" %d %d\n",freest[i],freesize[i]);

printf("\n\n");

while(1)

printf("1.Create.\n");

printf("2.Delete.\n");

printf("3.Compaction.\n");

printf("4.Exit.\n");

printf("Enter your choice: ");

scanf("%d",&ch);

switch(ch)

case 1:

printf("\nEnter the name of file: ");

scanf("%d",&name);

printf("\nEnter the size of the file: ");

scanf("%d",&size);

create(name,size);

break;

case 2:

printf("\nEnter the file name which u want to delete: ");

scanf("%d",&name);

33
del(name);

break;

case 3:

compaction();

printf("\nAfter compaction the tables will be:\n");

display();

break;

case 4:

exit(1);

default:

printf("\nYou have entered a wrong choice.\n");

void create(int name,int size)

int i,flag=1,j,a;

for(i=0;i<=m;i++)

if( freesize[i] >= size)

a=i,flag=0;

if(!flag)

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

n++;

fname[j]=name;

fsize[j]=size;

34
fstart[j]=freest[a];

freest[a]=freest[a]+size;

freesize[a]=freesize[a]-size;

printf("\n The memory map will now be: \n\n");

display();

else

printf("\nNo enough space is available.System compaction. ...... ");

flag=1;

compaction();

display();

for(i=0;i<=m;i++)

if( freesize[i] >= size)

a=i,flag=0;

if(!flag)

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

n++;

fname[j]=name;

fsize[j]=size;

fstart[j]=freest[a];

freest[a]+=size;

freesize[a]-=size;

printf("\n The memory map will now be: \n\n");

display();

35
}

else

printf("\nNo enough space.\n");

void del(int name)

int i,j,k,flag=1;

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

if(fname[i]==name)

break;

if(i==n)

flag=0;

printf("\nNo such process exists. ..... \n");

else

m++;

freest[m]=fstart[i];

freesize[m]=fsize[i];

for(k=i;k<n;k++)

fname[k]=fname[k+1];

fsize[k]=fsize[k+1];

fstart[k]=fstart[k+1];

36
}

n--;

if(flag)

printf("\n\n After deletion of this process the memory map will be : \n\n");

display();

void compaction()

int i,j,size1=0,f_size=0;

if(fstart[0]!=start)

fstart[0]=start;

for(i=1;i<n;i++)

fstart[i]=fstart[i-1]+fsize[i-1];

else

for(i=1;i<n;i++)

fstart[i]=fstart[i-1]+fsize[i-1];

f_size=freesize[0];

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

size1+=freesize[j];

37
freest[0]=freest[0]-(size1-f_size);

freesize[0]=size1;

m=0;

void display()

int i;

printf("\n *** MEMORY MAP TABLE *** \n");

printf("\n\nNAME SIZE STARTING ADDRESS \n\n");

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

printf(" %d%10d%10d\n",fname[i],fsize[i],fstart[i]);

printf("\n\n");

printf("\n\n*** FREE SPACE TABLE ***\n\n");

printf("FREE START ADDRESS FREE SIZE \n\n");

for(i=0;i<=m;i++)

printf(" %d %d\n",freest[i],freesize[i]);

Output:

38
Viva Questions
1) What is fragmentation?
2) Discuss the need of compaction.
3) Explain the term “paging”.
4) List various page replacement algorithms.
5) Explain resource allocation use in memory

39
EXPERIMENT NO. - 8

AIM: Implementation of resource allocation graph (RAG).

Procedure:
The resource allocation graph is a graphical representation of a system's status.As the
name implies, the resource allocation graph contains all of the information about all of
the processes holding some resources or waiting for some resources.It also contains
information on all instances of all resources, whether they are accessible or in use by the
processes.
Vertices
In RAG vertices are two types –
1. Process vertex - Every Process is represented as a process vertex. The process is
generally represented by a circle.
2. Resource vertex - Every resource is represented as a resource vertex.
It also has two types:
Single instance type resource: It is represented as a box with one dot within.
As a result, the number of dots indicates how many instances of each resource type
are present.
Multi-resource instance type resource: It is also represented as a box with multiple
dots within.

Algorithm:
1. First, find the currently available instances of each resource.
2. Check for each process which can be executed using the allocated + available
resource.
3. Add the allocated resource of the executable process to the available resources
and terminate it.
4. Repeat the 2nd and 3rd steps until the execution of each process.
5. If at any step, none of the processes can be executed then there is a deadlock
in the system.

Code/Method:
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
void waitexample()
{
int i, stat;
pid_t pid[5];
for(i=0; i<5; i++)
{

40
if ((pid[i] = fork()) = =0)
{
sleep(1);
exit(100+i);
}
}
//Using waitpid() and printing exit status
//of children.
for(i=0; i<5: i++)
{
pid_t cpid = waitpid(pid[i], &stat, 0);
if (WIFEXITED(stat))
printf("Child %d terminated with status: %d\n", cpid,
WEXITSTATUS(stat));
}
}
int main()
{
waitexample();
return0;
}

Output:

Viva Questions
1) What do you understand by computing resource?
2) Discuss types of vertices in RAG.
3) Compare single and multi-instance resource type.
4) Explain resource allocation graph.
5) How RAG helps for detection of deadlock?

41
EXPERIMENT NO. - 9

AIM: Implementation of Banker’s algorithm.

Procedure:

Deadlock avoidance & Dead Lock Prevention:


When a new process enters a system, it must declare the maximum number of
instances of each resource type it needed. This number may exceed the total number
of resources in the system. When the user requests a set of resources, the system must
determine whether the allocation of each resource will leave the system in safe state.
If it will the resources are allocation; otherwise, the process must wait until some
other process release the resources.

Data structures
• n-Number of processes, m-number of resource types.
• Available: Available[j]=k, k – instance of resource type Rj is available.
• Max: If max[i, j]=k, Pi may request at most k instances resource Rj.
• Allocation: If Allocation [i, j]=k, Pi allocated to k instances of resource
Rj
• Need: If Need[I, j]=k, Pi may need k more instances of resource type
Rj, Need[I, j]=Max[I, j]-Allocation[I, j];

Algorithm:

Safety Algorithm:
1. Work and Finish be the vector of length m and n respectively,
Work=Available and Finish[i] =False.
2. Find an i such that both
• Finish[i] =False
• Need<=Work
If no such I exists go to step 4.
3. work=work+Allocation, Finish[i] =True;
4. if Finish[1]=True for all I, then the system is in safe state.

Resource request algorithm:

Let Request i be request vector for the process Pi, If request i=[j]=k, then process Pi
wants k instances of resource type Rj.
1. if Request<=Need I go to step 2. Otherwise raise an error condition.

42
2. if Request<=Available go to step 3. Otherwise Pi must since the
resources are available.
3. Have the system pretend to have allocated the requested resources to
process Pi by modifying the state as follows;
Available=Available-Request I; Allocation I =Allocation+Request I; Need i=Need i-
Request I;
If the resulting resource allocation state is safe, the transaction is completed and
process Pi is allocated its resources. However, if the state is unsafe, the Pi must wait
for Request i and the old resource-allocation state is restored.

Code/Method:

/* BANKER’S ALGORITHM */
#include<stdio.h> #include<conio.h> struct da
{
int max[10],a1[10],need[10],before[10],after[10];
}p[10];
void main()
{
int i,j,k,l,r,n,tot[10],av[10],cn=0,cz=0,temp=0,c=0; clrscr();
printf("\n ENTER THE NO. OF PROCESSES:");
scanf("%d",&n);
printf("\n ENTER THE NO. OF RESOURCES:");
scanf("%d",&r); for(i=0;i<n;i++)
{
printf("PROCESS %d \n",i+1); for(j=0;j<r;j++)
{
printf("MAXIMUM VALUE FOR RESOURCE %d:",j+1);
scanf("%d",&p[i].max[j]);
}
for(j=0;j<r;j++)
{
printf("ALLOCATED FROM RESOURCE %d:",j+1);
scanf("%d",&p[i].a1[j]); p[i].need[j]=p[i].max[j]-p[i].a1[j];
}
}
for(i=0;i<r;i++)
{
printf("ENTER TOTAL VALUE OF RESOURCE %d:",i+1);
scanf("%d",&tot[i]);
}
for(i=0;i<r;i++)
{
for(j=0;j<n;j++) temp=temp+p[j].a1[i]; av[i]=tot[i]-temp; temp=0;

43
}
printf("\n\t RESOURCES ALLOCATED NEEDED TOTAL AVAIL");
for(i=0;i<n;i++)
{
printf("\n P%d \t",i+1);
for(j=0;j<r;j++)
printf("%d",p[i].max[j]);
printf("\t");
for(j=0;j<r;j++)
printf("%d",p[i].a1[j]);
printf("\t"); for(j=0;j<r;j++)
printf("%d",p[i].need[j]);
printf("\t"); for(j=0;j<r;j++)
{
if(i==0) printf("%d",tot[j]);
}
printf(""); for(j=0;j<r;j++)
{
if(i==0) printf("%d",av[j]);
}

}
printf("\n\n\t AVAIL BEFORE\T AVAIL AFTER "); for(l=0;l<n;l++)
{
for(i=0;i<n;i++)
{
for(j=0;j<r;j++)
{
if(p[i].need[j] >av[j]) cn++; if(p[i].max[j]==0) cz++;
}
if(cn==0 && cz!=r)
{
for(j=0;j<r;j++)
{
p[i].before[j]=av[j]-p[i].need[j];
p[i].after[j]=p[i].before[j]+p[i].max[j]; av[j]=p[i].after[j];
p[i].max[j]=0;
}
printf("\n P %d \t",i+1); for(j=0;j<r;j++) printf("%d",p[i].before[j]); printf("\t");
for(j=0;j<r;j++) printf("%d",p[i].after[j]);
cn=0; cz=0; c++;
break;
}
else

44
{
cn=0;cz=0;
}
}
}
if(c==n)
printf("\n THE ABOVE SEQUENCE IS A SAFE SEQUENCE");
else
printf("\n DEADLOCK OCCURED");
getch();
}

Output:

ENTER THE NO. OF PROCESSES:4

ENTER THE NO. OF RESOURCES:3


PROCESS 1
MAXIMUM VALUE FOR RESOURCE 1:3
MAXIMUM VALUE FOR RESOURCE 2:2
MAXIMUM VALUE FOR RESOURCE 3:2
ALLOCATED FROM RESOURCE 1:1
ALLOCATED FROM RESOURCE 2:0
ALLOCATED FROM RESOURCE 3:0
PROCESS 2
MAXIMUM VALUE FOR RESOURCE 1:6
MAXIMUM VALUE FOR RESOURCE 2:1
MAXIMUM VALUE FOR RESOURCE 3:3
ALLOCATED FROM RESOURCE 1:5
ALLOCATED FROM RESOURCE 2:1
ALLOCATED FROM RESOURCE 3:1
PROCESS 3
MAXIMUM VALUE FOR RESOURCE 1:3
MAXIMUM VALUE FOR RESOURCE 2:1
MAXIMUM VALUE FOR RESOURCE 3:4
ALLOCATED FROM RESOURCE 1:2
ALLOCATED FROM RESOURCE 2:1
ALLOCATED FROM RESOURCE 3:1
PROCESS 4
MAXIMUM VALUE FOR RESOURCE 1:4
MAXIMUM VALUE FOR RESOURCE 2:2

45
MAXIMUM VALUE FOR RESOURCE 3:2
ALLOCATED FROM RESOURCE 1:0
ALLOCATED FROM RESOURCE 2:0
ALLOCATED FROM RESOURCE 3:2
ENTER TOTAL VALUE OF RESOURCE 1:9
ENTER TOTAL VALUE OF RESOURCE 2:3
ENTER TOTAL VALUE OF RESOURCE 3:6

RESOURCES ALLOCATED NEEDED TOTAL AVAIL


P1 322 100 222 936
112
P2 613 511 102

P3 314 211 103

P4 422 002 420

AVAIL BEFORE AVAIL AFTER


P2 010 623
P1 401 723
P3 620 934
P4 514 936

THE ABOVE SEQUENCE IS A SAFE


SEQUENCE

Viva Questions
1.) What is meant by Deadlock?
2.) What is safe state in Banker’s Algorithm?
3.) What is Banker’s algorithm?
4.) What are necessary conditions for deadlock?
5.) What are principles and goals of protection?

46
EXPERIMENT NO. - 10

AIM: Conversion of resource allocation graph (RAG) to wait for graph


(WFG) for each type of method used for storing graph.

Procedure:
One such deadlock detection algorithm makes use of a wait-for graph to track which other
processes a process is currently blocking on. In a wait-for graph, processes are represented
as nodes, and an edge from process Pi to Pj implies Pj is holding a resource that Pi
needs and thus Pi is waiting for Pj to release its lock on that resource. There may be
processes waiting for more than a single resource to become available. Graph cycles imply
the possibility of a deadlock.

Code/Method:
STEPS TO PERFORM:
(i) Identify the waiting processes in the RAG.
(ii) Accordingly draw Wait-for graph for the given RAG.
(iii) To draw it as graphical representation, we introduce graphics.h and
work in graphics mode.
(iv) Geometric images are entered by entering graphics, providing with
parameter and closing graphics.
(v) We now identify circular chain of dependency (i.e., appearance of
loops in the graph)
Output:
The wait-for-graph (graphical representation). Also, check presence of loop.

Viva Questions
1) Discuss the conversion of RAG to WFG.
2) How can you detect deadlock using wait for graph?
3) Explain the process of deadlock recovery.
4) How deadlock can be prevented or avoided?
5) Explain the necessary conditions for deadlock.

47
EXPERIMENT NO. - 11

AIM: Implement the solution for Bounded Buffer (producer-


consumer) problem using inter process communication techniques-
Semaphores.

Procedure:
Producer consumer problem is a synchronization problem. There is a fixed size buffer
where the producer produces items and that is consumed by a consumer process. One
solution to the producer- consumer problem uses shared memory. To allow producer and
consumer processes to run concurrently, there must be available a buffer of items that can
be filled by the producer and emptied by the consumer. This buffer will reside in a
region of memory that is shared by the producer and consumer processes. The producer
and consumer must be synchronized, so that the consumer does not try to consume an
item that has not yet been produced.

Code/Method:

#include <stdio.h>
#include <stdlib.h>

// Initialize a mutex to 1
intmutex = 1;

// Number of full slots as 0


intfull = 0;

// Number of empty slots as size


// of buffer
intempty = 10, x = 0;

// Function to produce an item and


// add it to the buffer
voidproducer()
{
// Decrease mutex value by 1
--mutex;

// Increase the number of full


// slots by 1
++full;

// Decrease the number of empty


// slots by 1
--empty;

48
// Item produced
x++;
printf("\nProducer produces"
"item %d",
x);

// Increase mutex value by 1


++mutex;
}

// Function to consume an item and


// remove it from buffer
voidconsumer()
{
// Decrease mutex value by 1
--mutex;

// Decrease the number of full


// slots by 1
--full;

// Increase the number of empty


// slots by 1
++empty;
printf("\nConsumer consumes "
"item %d",
x);
x--;

// Increase mutex value by 1


++mutex;
}

// Driver Code
intmain()
{
intn, i;
printf("\n1. Press 1 for Producer"
"\n2. Press 2 for Consumer"
"\n3. Press 3 for Exit");

// Using '#pragma omp parallel for'


// can give wrong value due to
// synchronization issues.

// 'critical' specifies that code is


// executed by only one thread at a
// time i.e., only one thread enters

49
// the critical section at a given time
#pragma omp critical

for(i = 1; i > 0; i++) {

printf("\nEnter your choice:");


scanf("%d", &n);

// Switch Cases
switch(n) {
case1:

// If mutex is 1 and empty


// is non-zero, then it is
// possible to produce
if((mutex == 1)
&& (empty != 0)) {
producer();
}

// Otherwise, print buffer


// is full
else{
printf("Buffer is full!");
}
break;

case2:

// If mutex is 1 and full


// is non-zero, then it is
// possible to consume
if((mutex == 1)
&& (full != 0)) {
consumer();
}

// Otherwise, print Buffer


// is empty
else{
printf("Buffer is empty!");
}
break;

// Exit Condition
case3:
exit(0);
break;

50
}
}
}

Output:

Viva Questions
1) What is bounded buffer problem?
2) What is process synchronization?
3) What is critical section?
4) What is frame buffer?
5) Explain Mutual Exclusion.

51
EXPERIMENT NO.- 12

AIM: Implement the solutions for Readers-Writer’s problem using


inter process communication technique –Semaphore.

Procedure:
The readers-writers problem relates to an object such as a file that is shared between
multiple processes. Some of these processes are readers i.e., they only want to read
the data from the object and some of the processes are writers i.e., they want to write into
the object.
The readers-writers problem is used to manage synchronization so that there are no
problems with the object data. For example - If two readers access the object at the same
time there is no problem. However, if two writers or a reader and writer access the
object at the same time, there may be problems.
To solve this situation, a writer should get exclusive access to an object i.e., when a writer
is accessing the object, no reader or writer may access it. However, multiple readers can
access the object at the same time.

Code/Method:
#include<semaphore.h>
#include<stdio.h>
#include<stdlib.h>
sem_t x,y;
pthread_t tid;
pthread_t writerthreads[100],readerthreads[100];
int readercount;

void *reader(void* param)


{
sem_wait(&x);
readercount++;
if(readercount==1)
sem_wait(&y);
sem_post(&x);
printf("\n%d reader is inside",readercount);
sem_wait(&x);
readercount--;
if(readercount==0)
{
sem_post(&y);
}
sem_post(&x);
printf("\n%d Reader is leaving",readercount+1);
}

void *writer(void* param)

52
{
printf("\nWriter is trying to enter");
sem_wait(&y);
printf("\nWriter has entered");
sem_post(&y);
printf("\nWriter is leaving");
}

int main()
{
int n2,i;
printf("Enter the number of readers:");
scanf("%d",&n2);
int n1[n2];
sem_init(&x,0,1);
sem_init(&y,0,1);
for(i=0;i<n2;i++)
{
pthread_create(&writerthreads[i],NULL,reader,NULL);
pthread_create(&readerthreads[i],NULL,writer,NULL);
}
for(i=0;i<n2;i++)
{
pthread_join(writerthreads[i],NULL);
pthread_join(readerthreads[i],NULL);
}

Output:
reader is inside
reader is leaving
reader is inside
reader is leaving
writer is trying to enter
writer has entered
writer is leaving

Viva Questions
1) What is critical section problem?
2) What is semaphore?
3) Define concurrent process.
4) What is reader writer problem?
5) Define Various Application of semaphore.

53

You might also like