Experiment No.
06
AIM: To write a C-program to implement the producer – consumer problem using semaphores.
Introduction:
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.
PROGRAM
#include<stdio.>
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
break;;;
printf(“\nEnter the value: “);
scanf(“%d”, &produce);
buffer[in] = produce;
in = (in+1)%bufsize;
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;
}}}
OUTPUT
1. Produce 2. Consume 3. Exit
Enter your choice: 2
Buffer is Empty
1. Produce 2. Consume 3. Exit
Enter your choice: 1
Enter the value: 100
1. Produce 2. Consume 3. Exit
Enter your choice: 2
The consumed value is 100
1. Produce 2. Consume 3. Exit
Enter your choice: 3
Conclusion: Hence we have implemented a C-program to implement the producer – consumer
problem using semaphores.
Experiment No.07
Aim: Write a program to demonstrate the concept of deadlock avoidance through Banker‟s
Algorithm.
Introduction:
In a multiprogramming environment, several processes may compete for a finite number
of resources. A process requests resources; if the resources are not available at that time, the process
enters a waiting state. Sometimes, a waiting process is never again able to change state, because the
resources it has requested are held by other waiting processes. This situation is called a
[Link] avoidance is one of the techniques for handling deadlocks. This approach
requires that the operating system be given in advance additional information concerning which
resources a process will request and use during its lifetime. With this additional knowledge, it can
decide for each request whether or not the process should wait. To decide whether the current request
can be satisfied or must be delayed, the system must consider the resources currently available, the
resources currently allocated to each process, and the future requests and releases of each process.
Banker’s algorithm is a deadlock avoidance algorithm that is applicable to a system with multiple
instances of each resource type.
ALGORITHM:
Step 1: Start the Program.
Step 2: Obtain the required data through char and int datatypes.
Step 3: Enter the filename, index block.
Step 4: Print the file name index loop.
Step 5: File is allocated to the unused index blocks.
Step 6: This is allocated to the unused linked allocation.
Step 7: Stop the execution.
PROGRAM:
SOURCE CODE:
/* Bankers algorithm for Deadlock Avoidance */
#include<stdio.h>
struct process
int allocation[3];
int max[3];
int need[3];
int finish;
}p[10];
int main()
int n,i,I,j,avail[3],work[3],flag,count=0,sequence[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;
}
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
$ ./[Link]
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
Conclusion:
Thus the program for procedure-consumer problem is executed and verified successfully.
Experiment No.08
AIM: To write a c program to implement IPC using shared memory.
Introduction:
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.
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
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.. Once retrieved, the message is no longer available in the queue.
Algorithm:-
The shared memory identifier associated with key The argument key is equal to IPC_PRIVATE.
[Link]
step [Link] header files required for the program are #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
step [Link] the variable which are required as pid_t pid
int *shared /* pointer to the shm */ int shmid
step [Link] shmget function to create shared memory
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg)
The shmget() function shall return the operating system selects the next availablekey for a newly
created shared block of [Link] represents size of shared memory block Shmflg shared
memory permissions which are represented by octalinteger shmid = shmget(IPC_PRIVATE,
sizeof(int), IPC_CREAT | 0666);
print the shared memory id step [Link] fork()==0 Then
begin
end
step [Link]
begin
end
step [Link].
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>
int main(void) {
pid_t pid;
int *shared; /* pointer to the shm */ i
nt shmid;
shmid = shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT | 0666);
printf("Shared Memory ID=%u",shmid);
if (fork() == 0){ /
* Child */
/* Attach to shared memory and print the pointer */
shared = shmat(shmid, (void *) 0, 0);
printf("Child pointer %u\n", shared);
*shared=1;
printf("Child value=%d\n", *shared);
sleep(2);
printf("Child value=%d\n", *shared);
Else
{ /* Parent */
/* Attach to shared memory and print the pointer */
shared = shmat(shmid, (void *) 0, 0);
printf("Parent pointer %u\n", shared);
printf("Parent value=%d\n", *shared);
sleep(1);
*shared=42;
printf("Parent value=%d\n", *shared);
sleep(5);
shmctl(shmid, IPC_RMID, 0);
}}
OUTPUT:
$cc shared_mem.c
$ ./[Link]
Shared Memory ID=65537
Child pointer 3086680064
Child value=1
Shared Memory ID=65537
Parent pointer 3086680064
Parent value=1
Parent value=42
Child value=42
Conclusion: A program to implement IPC using shared memory has been successfully verified.
Experiment No.-09
AIM: To write a C program for implementation memory allocation methods for fixed partition using
first fit.
Introduction:
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.
Program:
#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++)
#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++)
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)
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:-
File 1: 1
File 2: 4
OUTPUT
File No File Size Block No Block Size Fragment
11376
24151
Conclusion: Hence we have done implementation of memory allocation methods for fixed partition
using first fit.
Experiment No.-10
AIM: To write a C program for implementation of FCFS and SJF scheduling algorithms.
Introduction:
One of the responsibilities of the operating system is to use the hardware efficiently. For the disk
drives, meeting this responsibility entails having fast access time and large disk bandwidth. Both the
access time and the bandwidth can be improved by managing the order in which disk I/O requests
are serviced which is called as disk scheduling. 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. In the SCAN algorithm, the disk arm starts at one end, and
moves towards the other end, servicing requests as it reaches each cylinder, until it gets to the other
end of the disk. At the other end, the direction of head movement is reversed, and servicing
continues. The head continuously scans back and forth across the disk. C-SCAN is a variant of
SCAN designed to provide a more uniform wait time. Like SCAN, C-SCAN moves the head from
one end of the disk to the other, servicing requests along the way. When the head reaches the other
end, however, it immediately returns to the beginning of the disk without servicing any requests on
the return trip
PROGRAM
FCFS DISK SCHEDULING ALGORITHM
#include<stdio.h
main()
int t[20], n, I, j, tohm[20], tot=0; float avhm;
clrscr();
printf(“enter the [Link] tracks”);
scanf(“%d”,&n);
printf(“enter the tracks to be traversed”);
for(i=2;i<n+2;i++)
scanf(“%d”,&t*i+);
for(i=1;i<n+1;i++){
tohm[i]=t[i+1]-t[i]; if(tohm[i]<0) tohm[i]=tohm[i]*(-1);
for(i=1;i<n+1;i++)
printf(“%d\t\t\t%d\n”,t*i+,tohm*i+);
printf("\nAverage header movements:%f",avhm);
getch();
INPUT
Enter [Link] tracks:9
Enter track position:55 58 60 70 18 90 150 160 184
OUTPUT
Tracks traversed
Difference between tracks
55 45
58 3
60 2
70 10
18 52
90 72
150 60
160 10
184 24
Conclusion: Hence we have successfully done implementation of FCFS and SJF scheduling
algorithms.