Os Lab File
Os Lab File
:
AIM: Write a program to find average waiting and turnaround time
for First Come First Serve (FCFS) Scheduling algorithm.
DESCRIPTION :
FCFS also termed as First-In-First-Out i.e. allocate the CPU in order in which the process arrive.
When the CPU is free, it is allowed to process, which is occupying the front of the queue. Once
this process goes into running state, its PCB is removed from the queue.
INPUT:
n= number of processes
Arrival time and Burst time for each process
PROGRAM CODE:
#include<bits/stdc++.h>
int main()
{
int i,j,n,at,bt,temp,temp1,temp2,awt[50],c,c_loc;
float awtime,att[50],burst,attime,a_wait;
int mat[50][3];
awt[0]=0;
a_wait=mat[0][1];
for(i=0;i<n-1;i++)
{ awt[i+1]=a_wait+(mat[i][2]-mat[i+1][1]);
a_wait=a_wait+mat[i][2];
}
for(i=0;i<n;i++)
awtime=awtime+awt[i];
awtime=awtime/n;
printf("\nAvg. Waiting time= %f",awtime);
att[0]=mat[0][2]-mat[0][1];
burst=mat[0][2];
for(i=1;i<n;i++)
{ burst=burst+mat[i][2];
att[i]=(burst-mat[i][1]);
}
for(i=0;i<n;i++)
attime=attime+att[i];
attime=attime/n;
printf("\nAvg. Turnaround time=%f",attime);
}
OUTPUT:
RESULT:
Average waiting time and Average turnaround time
DISCUSSION:
First Come First Served (FCFS) is a Non-Preemptive scheduling algorithm.
Advantage
1.Suitable for batch system.
2.It is simple to understand and code.
Disadvantage:
1. Waiting time can be large if short request wait behind the long process.
2. It is not suitable for time sharing system where it is important that each user should get the
CPU for equal amount of time interval.
DESCRIPTION:
Shortest job next (SJN), also known as shortest job first (SJF) or shortest process next (SPN), is a
scheduling policy that selects for execution the waiting process with the smallest execution
time. SJN is a non-preemptive algorithm. Shortest remaining time is a preemptive variant of
SJN. Shortest job next is advantageous because of its simplicity and because it minimizes the
average amount of time each process has to wait until its execution is complete. However, it
has the potential for process starvation for processes which will require a long time to
complete if short processes are continually added. Highest response ratio next is similar but
provides a solution to this problem using a technique called aging. Non-Preemptive scheduling:
When a process enters the state of running, the state of that process is not deleted from the
scheduler until it finishes its service time.
INPUT:
1. we first input n (Integer) , denoting total number of processes.
2. we input Burst Time for all the respective processes.
3. we also input arrival time of each and every process. Here we take help of 2d array of size
Nx5, and apply brute forced method to solve this shortest job first algorithm.
Program Code:
#include<stdio.h>
#include<conio.h>
int Twt,Ttt,A[20],Wt[20],n,Bu[20];
float Att,Awt;
char pname[20][20];
void getdata();
void output();
void sjf();
void getdata()
{
int i;
printf("Enter the number of processes: ");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
fflush(stdin);
printf("Enter the process name: ");
scanf("%s",&pname[i]);
printf("Enter The BurstTime for Process %s: ",pname[i]);
scanf("%d",&Bu[i]);
printf("Enter the Arrival Time for Process %s: ",pname[i]);
scanf("%d",&A[i]);
}
}
void output()
{
int i;
printf("\nFinal Output");
for(i=1;i<=n;i++)
printf("\t%s\t",pname[i]);
printf("\t\n");
printf("\n");
for(i=1;i<=n;i++)
printf("%d\t\t",Wt[i]);
printf("%d",Wt[n]+Bu[n]);
printf("\n");
}
void sjf()
{
int w,t,i,B[10],Tt=0,temp,j;
char S[10],c[20][20];
int temp1;
printf("\nSHORTEST JOB FIRST SCHEDULING ALGORITHM.");
Twt=Ttt=0;
w=0;
for(i=1;i<=n;i++)
{
B[i]=Bu[i];
S[i]='T';
Tt=Tt+B[i];
}
for(i=1;i<=n;i++)
{
for(j=3;j<=n;j++)
{
if(B[j-1]>B[j])
{
temp=B[j-1];
temp1=A[j-1];
B[j-1]=B[j];
A[j-1]=A[j];
B[j]=temp;
A[j]=temp1;
strcpy(c[j-1],pname[j-1]);
strcpy(pname[j-1],pname[j]);
strcpy(pname[j],c[j-1]);
}
}
}
Wt[1]=0;
w=w+B[1];
t=w;
S[1]='F';
while(w<Tt)
{
i=2;
while(i<=n)
{
if(S[i]=='T'&&A[i]<=t)
{
Wt[i]=w;
S[i]='F';
w=w+B[i];
t=w;
i=2;
}
else
i++;
}
}
for(i=1;i<=n;i++)
{
Twt=Twt+(Wt[i]-A[i]);
Ttt=Ttt+((Wt[i]+Bu[i])-A[i]);
}
Att=(float)Ttt/n;
Awt=(float)Twt/n;
printf("\nAverage Turn around time=%3.2f",Att);
printf("\nAverageWaiting Time=%3.2f",Awt);
output();
}
void main()
{
clrscr();
getdata();
sjf();
getch();
}
OUTPUT
RESULT: Turn-around time and waiting time of all the processes whose arrival time and
Burst time are given is shown in output. Thus we are able to get turn-around time and waiting
time of all the processes.
DISCUSSION:
1 It is advantageous because of its simplicity and because it minimizes the average amount of
time each process has to wait until its execution is complete
2. It has the potential for process starvation for processes which will require a long time to
complete if short processes are continually added.
3. Total execution time of a job must be known before execution.
4. While it is impossible to predict execution time perfectly, several methods can be used to
estimate it, such as a weighted average of previous execution times.
DESCRIPTION: Shortest remaining time, also known as shortest remaining time first
(SRTF), is a scheduling method that is a preemptive version of shortest job next scheduling. In
this scheduling algorithm, the process with the smallest amount of time remaining until
completion is selected to execute. Since the currently executing process is the one with the
shortest amount of time remaining by definition, and since that time should only reduce as
execution progresses, processes will always run until they complete or a new process is added
that requires a smaller amount of time.
INPUT:
N=Number of process
Arrival and burst time for each process
PROGRAM CODE:
#include<bits/stdc++.h>
int time=0;
int find(int a[], int n, int nburst[]);
int main()
{
int c,n, i,j=0,k, min,flag=0, sum=0;
int a[10],b[10],arr[10],burst[10],nburst[10],gantt[30];
int turn[10]={0}, wait[10]={0};
float sum1=0,sum2=0;
printf("Enter the number of processes: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter the arrival time of P%d : ",i);
scanf("%d",&arr[i]);
printf("Enter the burst time of P%d : ",i);
scanf("%d",&burst[i]);
nburst[i]=burst[i];
}
for(i=0;i<n;i++)
sum+=burst[i];
for(i=0;i<sum;i++)
{
min=find(arr,n,nburst);
gantt[time++]=min;
nburst[min]--;
}
/*printf("\nGantt chart: \n");
for(i=0;i<sum;i++)
printf("t%d: P%d\t\t",i,gantt[i]);
*/
//Calculating turnaround time
for(i=0;i<n;i++)
a[i]=i; //a[] now contains the process number
for(i=sum-1;i>=0;i--)
{
j=gantt[i];
flag=0;
for(k=0;k<n;k++)
if(a[k]!=-1)
{
flag=1;
break;
}
if(flag==1)
{
if(gantt[i]==j && a[j]!=-1)
{ turn[j]=i-arr[j]+1;
a[j]=-1;
}
}
else
break;
}
printf("\nTurnaround time: \n");
for(i=0;i<n;i++)
{
printf("P%d : %d ",i,turn[i]);
sum1+=turn[i];
}
RESULT:
We get Average waiting and Turnaround time
DISCUSSION:
Unlike round robin scheduling algorithm , shortest remaining time scheduling algorithm may
lead to starvation . If the short processes are continually added to the cpu scheduler then the
currently running process will never be able to execute , hence SRT is not starvation free .
DESCRIPTION:
Round-robin (RR) is one of the algorithms employed by process and network schedulers in
computing. As the term is generally used, time slices (also known as time quanta) are assigned
to each process in equal portions and in circular order, handling all processes without priority
(also known as cyclic executive). Round-robin scheduling is simple, easy to implement, and
starvation-free. Round-robin scheduling can also be applied to other scheduling problems, such
as data packet scheduling in computer networks. It is an operating system concept. The name
of the algorithm comes from the round-robin principle known from other fields, where each
person takes an equal share of something in turn.
INPUT:
1 we first input n (Integer) , denoting total number of processes.
2. we input Burst Time for all the respective processes.
3. we also input arrival time of each and every process. Here we take help of structure having 6
varibales naming process no, execute, arrival time, burst time, wait time, turn around time. and
apply brute forced method to solve this shortest job first algorithm.
Program Code:
#include<bits/stdc++.h>
int main()
{
int cnt,j,n,time,remain,flag=0,t_quantum;
int wait_time=0,turnaround_time=0,at[10],bt[10],rt[10];
printf("Enter Total Process:\t ");
scanf("%d",&n);
remain=n;
for(cnt=0;cnt<n;cnt++)
{
printf("Enter Arrival Time and Burst Time for Process Process Number %d :",cnt+1);
scanf("%d",&at[cnt]);
scanf("%d",&bt[cnt]);
rt[cnt]=bt[cnt];
}
printf("Enter Time Quantum:\t");
scanf("%d",&t_quantum);
printf("\n\nProcess\t|Turnaround Time|Waiting Time\n\n");
for(time=0,cnt=0;remain!=0;)
{
if(rt[cnt]<=t_quantum && rt[cnt]>0)
{
time+=rt[cnt];
rt[cnt]=0;
flag=1;
}
else if(rt[cnt]>0)
{
rt[cnt]-=t_quantum;
time+=t_quantum;
}
if(rt[cnt]==0 && flag==1)
{
remain--;
printf("P[%d]\t|\t%d\t|\t%d\n",cnt+1,time-at[cnt],time-at[cnt]-bt[cnt]);
wait_time+=time-at[cnt]-bt[cnt];
turnaround_time+=time-at[cnt];
flag=0;
}
if(cnt==n-1)
cnt=0;
else if(at[cnt+1]<=time)
cnt++;
else
cnt=0;
}
printf("\nAverage Waiting Time= %f\n",wait_time*1.0/n);
printf("Avg Turnaround Time = %f",turnaround_time*1.0/n);
return 0;
}
OUTPUT:
;;
RESULT:
Turn-around time and waiting time of all the processes whose arrival time and Burst time are
given is shown in output. Thus we are able to get turn-around time and waiting time of all the
processes in round robin scheduling algorithm.
DISCUSSION:
Advantages
1. There is fairness since every process gets equal share of CPU.
2. The newly created process is added to end of ready queue.
3. A round-robin scheduler generally employs time-sharing, giving each job a time slot or
quantum.
Disadvantages
1. There is Larger waiting time and Response time.
2. There is Low throughput.
3. There is Context Switches.
DESCRIPTION:
System call fork() is used to create processes. It takes no arguments and returns a process ID.
The purpose of fork() is to create a new process, which becomes the child process of the caller.
After a new child process is created, both processes will execute the next instruction following
the fork() system call. Therefore, we have to distinguish the parent from the child.
This can be done by testing the returned value of fork():
1. If fork() returns a negative value, the creation of a child process was unsuccessful.
2. fork() returns a zero to the newly created child process.
3. fork() returns a positive value, the process ID of the child process, to the parent.
INPUT:
No input
Program Code:
#include<stdio.h>
main(int arc,char*ar[])
{
int pid;
char s[100];
pid=fork();
if(pid<0)
printf("error");
else if(pid>0)
{
wait(NULL);
printf("\n Parent Process:\n");
printf("\n\tParent Process id:%d\t\n",getpid());
execlp("cat","cat",ar[1],(char*)0);
error("can’t execute cat %s,",ar[1]);
}
else
{
printf("\nChild process:");
printf("\n\tChildprocess parent id:\t %d",getppid());
sprintf(s,"\n\tChild process id :\t%d",getpid());
write(1,s,strlen(s));
printf(" ");
printf(" ");
printf(" ");
execvp(ar[2],&ar[2]);
error("can’t execute %s",ar[2]);
}
}
OUTPUT:
DISCUSSION:
1. The fork operation creates a separate address space for the child. The child process has an
exact copy of all the memory segments of the parent process.
2. When a process calls fork, it is deemed the parent process and the newly created process is its
child. After the fork, both processes not only run the same program, but they resume execution
as though both had called the system call. They can then inspect the call's return value to
determine their status, child or parent, and act accordingly.
DESCRIPTION:
Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that repeatedly
steps through the list to be sorted, compares each pair of adjacent items and swaps them if they
are in the wrong order. The pass through the list is repeated until no swaps are needed, which
indicates that the list is sorted. The algorithm, which is a comparison sort, is named for the way
smaller or larger elements "bubble" to the top of the list. Although the algorithm is simple, it is
too slow and impractical for most problems even when compared to insertion sort. It can be
practical if the input is usually in sorted order but may occasionally have some out-of-order
elements nearly in position.
INPUT:
A file input.txt which contains all the input in sequential order as( n a[0] a[1] ...... a[n]).
To compile a program: gcc -o hello hello.c (hello is our object file) to run object file: ./hello
Program Code:
#include <stdio.h>
int main()
{ int i,j,temp,a[10];
//printf("Enter the 10 array elements to sort:\n");
FILE *fptr;
fptr=fopen("read.txt","r");
if(fptr==NULL)
{
printf("ERROR!Unable to open file");
return 0;
}
for(i=0;i<10;i++)
{
fscanf(fptr,"%d",&a[i]);
}
for(i=0;i<10;i++)
{
for(j=0;j<9-i;j++)
{
if(a[j]>a[j+1])
{
temp=a[j+1];
a[j+1]=a[j];
a[j]=temp;
}
}
}
fclose(fptr);
fptr=fopen("write.txt","w");
if(fptr==NULL)
{
printf("ERROR!Unable to open file");
return 0;
}
fprintf(fptr,"The sorted array is:\n");
for(i=0;i<10;i++)
{
fprintf(fptr,"%d\t",a[i]);
}
fprintf(fptr,"\n");
fclose(fptr);
return 0;
}
OUTPUT :
RESULT:
Resulted output in input.txt file is now sorted.
DISCUSSION:
Bubble sort is a basic technique to sort an array of elements.-However it is not that good
(efficient) but it just gives us a way/method to sort a list of elements in increasing/decreasing
order.
We can simply use g++ and gcc compilers in ubuntu without need of actual ide .(integrated
development environment)
DESCRIPTION:
The Banker's algorithm, sometimes referred to as the avoidance algorithm, is a resource-allocation
and deadlock avoidance algorithm developed by Edsger Djkestra that tests for safety by simulating
the allocation of predetermined maximum possible amounts of all resources, and then makes an
"s-state" check to test for possible deadlock conditions for all other pending activities, before
deciding whether allocation should be allowed to continue. When a new process enters a system,
it must declare the maximum number of instances of each resource type that it may ever claim;
clearly, that number may not exceed the total number of resources in the system. Also, when a
process gets all its requested resources it must return them in a finite amount of time.
INPUT:
Integer n denoting total number of process.
Integer m denoting total types of resources.
a[i] denoting total amount of present resources of type i.
Matrix element M[i][j] denoting current situation of allocated resources.
Maximal matrix element c[i][j] denoting maximum resources of each type every process
requires.
Program Code:
#include <stdio.h>
int current[5][5], maximum_claim[5][5], available[5];
int allocation[5] = {0, 0, 0, 0, 0};
int maxres[5], running[5], safe = 0;
int counter = 0, i, j, exec, resources, processes, k = 1;
int main()
{
printf("\nEnter number of processes: ");
scanf("%d", &processes);
for (i = 0; i < processes; i++)
{
running[i] = 1;
counter++;
}
printf("\nEnter number of resources: ");
scanf("%d", &resources);
printf("\nEnter Claim Vector:");
for (i = 0; i < resources; i++)
{
scanf("%d", &maxres[i]);
}
printf("\nEnter Allocated Resource Table:\n");
for (i = 0; i < processes; i++)
{
for(j = 0; j < resources; j++)
{
scanf("%d", ¤t[i][j]);
}
}
printf("\nEnter Maximum Claim Table:\n");
for (i = 0; i < processes; i++)
{
for(j = 0; j < resources; j++)
{
scanf("%d", &maximum_claim[i][j]);
}
}
printf("\nThe Claim Vector is: ");
for (i = 0; i < resources; i++)
{
printf("\t%d", maxres[i]);
}
printf("\nThe Allocated Resource Table:\n");
for (i = 0; i < processes; i++)
{
for (j = 0; j < resources; j++)
{
printf("\t%d", current[i][j]);
}
printf("\n");
}
printf("\nThe Maximum Claim Table:\n");
for (i = 0; i < processes; i++)
{
for (j = 0; j < resources; j++)
{
printf("\t%d", maximum_claim[i][j]);
}
printf("\n");
}
for (i = 0; i < processes; i++)
{
for (j = 0; j < resources; j++)
{
allocation[j] += current[i][j];
}
}
printf("\nAllocated resources:");
for (i = 0; i < resources; i++)
{
printf("\t%d", allocation[i]);
}
for (i = 0; i < resources; i++)
{
available[i] = maxres[i] - allocation[i];
}
printf("\nAvailable resources:");
for (i = 0; i < resources; i++)
{
printf("\t%d", available[i]);
}
printf("\n");
while (counter != 0)
{
safe = 0;
for (i = 0; i < processes; i++)
{
if (running[i])
{
exec = 1;
for (j = 0; j < resources; j++)
{
if (maximum_claim[i][j] - current[i][j] >
available[j])
{
exec = 0;
break;
}
}
if (exec)
{
printf("\nProcess%d is executing\n", i + 1);
running[i] = 0;
counter--;
safe = 1;
for (j = 0; j < resources; j++)
{
available[j] += current[i][j];
}
break;
}
}
}
if (!safe)
{
printf("\nThe processes are in unsafe state.\n");
break;
}
else
{
printf("\nThe process is in safe state");
printf("\nAvailable vector:");
for (i = 0; i < resources; i++)
{
printf("\t%d", available[i]);
}
printf("\n");
}
}
return 0;
}
OUTPUT :
RESULT: In the given set of situations, system is in safe state. Even if situation will be in
unsafe state, our program will detect and output it to the output screen.
DISCUSSION:
1. If the necessary conditions for a deadlock are in place, it is still possible to avoid deadlock by
being careful when resources are allocated. Perhaps the most famous deadlock avoidance
algorithm, due to Dijkstra [1965], is the Banker’s algorithm. So named because the process is
analogous to that used by a banker in deciding if a loan can be safely made.
2. It needs to know how much of each resource a process could possibly request. In most
systems, this information is unavailable, making it impossible to implement the Banker's
algorithm. Also, it is unrealistic to assume that the number of processes is static since in most
systems the number of processes varies dynamically.