C Programs - OS
C Programs - OS
Date:
Aim
To create a new child process using fork system call.
fork()
The fork system call is used to create a new process called child process.
o The return value is 0 for a child process.
o The return value is negative if process creation is unsuccessful.
o For the parent process, return value is positive
The child process is an exact copy of the parent process.
Both the child and parent continue to execute the instructions following fork call.
The child can start execution before the parent or vice-versa.
Algorithm
1. Declare a variable x to be shared by both child and parent.
2. Create a child process using fork system call.
3. If return value is -1 then
Print "Process creation unsuccessfull"
Terminate using exit system call.
4. If return value is 0 then
Print "Child process"
Print process id of the child using getpid system call
Print value of x
Print process id of the parent using getppid system call
5. Otherwise
Print "Parent process"
Print process id of the parent using getpid system call
Print value of x
Print process id of the shell using getppid system call.
6. Stop
Program
/ #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
pid_t pid; int
x = 5; pid =
fork(); x++;
if (pid < 0)
{
printf("Process creation error"); exit(-1);
}
else if (pid == 0)
{
printf("Child process:"); printf("\nProcess id is %d",
getpid()); printf("\nValue of x is %d", x);
printf("\nProcess id of parent is %d\n", getppid());
}
else
{
printf("\nParent process:"); printf("\nProcess id is
%d", getpid()); printf("\nValue of x is %d", x);
printf("\nProcess id of shell is %d\n", getppid());
}
}
Output
$ gcc fork.c
$ ./a.out Child
process:
Process id is 19499 Value
of x is 6
Process id of parent is 19498
Result
Thus a child process is created with copy of its parent's address space.
Exp# 3b wait system call
Date:
Aim
To block a parent process until child completes using wait system call.
wait()
The wait system call causes the parent process to be blocked until a child terminates.
When a process terminates, the kernel notifies the parent by sending the SIGCHLD signal
to the parent.
Without wait, the parent may finish first leaving a zombie child, to be adopted by init process
Algorithm
Program
<stdio.h>
#include <stdlib.h> #include
<unistd.h> #include
<sys/types.h> #include
<sys/wait.h>
main()
{
int i, status; pid_t pid;
pid = fork();
if (pid < 0)
{
printf("\nProcess creation failure\n"); exit(-1);
}
else if(pid > 0)
{
wait(NULL);
printf ("\nParent starts\nEven Nos: "); for
(i=2;i<=10;i+=2)
printf ("%3d",i);
printf ("\nParent ends\n");
}
else if (pid == 0)
{
printf ("Child starts\nOdd Nos: "); for
(i=1;i<10;i+=2)
printf ("%3d",i); printf ("\
nChild ends\n");
}
}
Output
$ gcc wait.c
$ ./a.out Child
starts
Odd Nos: 1 3 5 7 9
Child ends
Parent starts
Even Nos: 2 4 6 8 10
Parent ends
Result
Thus using wait system call zombie child processes were avoided.
Exp# 3c exec system call
Date:
Aim
To load an executable program in a child processes exec system call.
execl()
The exec family of function (execl, execv, execle, execve, execlp, execvp) is used by
the child process to load a program and execute.
execl system call requires path, program name and null pointer
Algorithm
Program
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
main()
{
pid_t pid;
switch(pid = fork())
{
case -1:
perror("Fork failed"); exit(-
1);
case 0:
printf("Child process\n");
execl("/bin/date", "date", 0); exit(0);
default:
wait(NULL);
printf("Child Terminated\n"); exit(0);
}
}
Output
$ gcc exec.c
$ ./a.out Child
process
Sat Feb 23 17:46:59 IST 2013
Child Terminated
Result
Thus the child process loads a binary executable file into its address space.
Exp# 3d stat system call
Date:
Aim
To display file status using stat system call.
exit()
The exit system call is used to terminate a process either normally or abnormally
Closes all standard I/O streams.
stat()
The stat system call is used to return information about a file as a structure.
Algorithm
1. Get filename as command line argument.
2. If filename does not exist then stop.
3. Call stat system call on the filename that returns a structure
4. Display members st_uid, st_gid, st_blksize, st_block, st_size, st_nlink, etc.,
5. Convert time members such as st_atime, st_mtime into time using ctime function
6. Compare st_mode with mode constants such as S_IRUSR, S_IWGRP, S_IXOTH
and display file permissions.
7. Stop
Program
/* File status - stat.c */
#include<stdio.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
printf("Permissions : ");
printf( (S_ISDIR(file.st_mode)) ? "d" : "-");
printf( (file.st_mode & S_IRUSR) ? "r" : "-");
printf( (file.st_mode & S_IWUSR) ? "w" : "-");
printf( (file.st_mode & S_IXUSR) ? "x" : "-");
printf( (file.st_mode & S_IRGRP) ? "r" : "-");
printf( (file.st_mode & S_IWGRP) ? "w" : "-");
printf( (file.st_mode & S_IXGRP) ? "x" : "-");
printf( (file.st_mode & S_IROTH) ? "r" : "-");
printf( (file.st_mode & S_IWOTH) ? "w" : "-");
printf( (file.st_mode & S_IXOTH) ? "x" : "-"); printf("\n");
Output
$ gcc stat.c
Result
Thus attributes of a file is displayed using stat system call.
Exp# 3f open system call
Date :
Aim
To create a file and to write contents.
open()
Used to open an existing file for reading/writing or to create a new file.
Returns a file descriptor whose value is negative on error.
The mandatory flags are O_RDONLY, O_WRONLY and O_RDWR
Optional flags include O_APPEND, O_CREAT, O_TRUNC, etc
The flags are ORed.
The mode specifies permissions for the file.
creat()
Used to create a new file and open it for writing.
It is replaced with open() with flags O_WRONLY|O_CREAT | O_TRUNC
Algorithm
1. Declare a character buffer buf to store 100 bytes.
2. Get the new filename as command line argument.
3. Create a file with the given name using open system call with O_CREAT and
O_TRUNC options.
4. Check the file descriptor.
a) If file creation is unsuccessful, then stop.
5. Get input from the console until user types Ctrl+D
a) Read 100 bytes (max.) from console and store onto buf using read system call
b) Write length of buf onto file using write system call.
6. Close the file using close system call.
7. Stop
Program
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include <fcntl.h>
printf("Press Ctrl+D at end in a new line:\n"); while((n = read(0, buf, sizeof(buf))) > 0)
{
len = strlen(buf); write(fd,
buf, len);
}
close(fd);
}
Output
$ gcc fcreate.c
Result
Thus a file has been created with input from the user. The process can be verified by
Using cat command
4. Implement the following CPU scheduling algorithms
a. Round Robin
AIM:
To write a program to implement the Round Robin CPU scheduling Algorithm
ALGORITHM:
#include<stdio.h>
#include<conio.h>
int TRUE = 0;
int FALSE = -1;
int tbt[30],bt[30],tat[30],n=0,wt[30],qt=0,tqt=0,time=0,lmore,t_tat=0,t_wt=0;
void main()
{
int i,j;
clrscr();
printf("\nEnter no. of processors:");
scanf("%d",&n);
printf("\nEnter Quantum Time:");
scanf("%d",&qt);
for(i=0;i<n;i++)
{
printf("\nEnter Burst Time of Processor[%d]:",i+1);
scanf("%d",&bt[i]);
tbt[i] = bt[i];
wt[i] = tat[i] = 0;
}lmore = TRUE;
while(lmore == TRUE)
{
lmore = FALSE;
for(i=0;i<n;i++)
{
if(bt[i] != 0)
wt[i] = wt[i] + (time - tat[i]); tqt = 1;
while(tqt <= qt && bt[i] !=0)
{
lmore = TRUE;
bt[i] = bt[i] -1;
tqt++;
time++;
tat[i] = time;
}
}
}
printf("\nProcessor ID\tBurstTime\tTurnAroundTime\tWaitingTime\n");
for(i=0;i<n;i++)
{
printf("Processor%d\t\t%d\t\t%d\t\t%d\n",i+1,tbt[i],tat[i],wt[i]); t_tat = t_tat + tat[i];
t_wt = t_wt + wt[i];
}
printf("\nTotal Turn Around Time:%d",t_tat); printf("\nAverage Turn Around Time:%d",t_tat/n);
printf("\nTotal Waiting Time:%d",t_wt); printf("\nAverage Waiting Time:%d",t_wt/n);
getch();
}
RESULT:
Thus the program to implement the Round Robin CPU scheduling Algorithm was written, executed
and the output was verified successfully.
b. SJF
AIM:
To write a program to implement the SJF (Shortest Job First) CPU scheduling Algorithm
ALGORITHM:
#include<stdio.h>
#include<conio.h>
int p[30],bt[30],tot_tat=0,wt[30],n,tot_wt=0,tat[30],SJF_wt=0,SJF_tat=0;
float awt,avg_tat,avg_wt;
void main()
{
int i;
clrscr();
printf("\nEnter the no.of processes \n");
scanf("%d",&n);
printf("Enter burst time for each process\n");
for(i=0;i<n;i++)
{
scanf("%d",&bt[i]);
p[i] = i;
}
sort();
WT_TA T(& SJF _tat,& SJF _ wt);
printf("\n\nTotal Turn around Time:%d",SJF_tat); printf("\nAverage Turn around Time :%d ", SJF_tat/n);
printf("\nTotal Waiting Time:%d",SJF_wt);
printf("\nTotal avg. Waiting Time:%d",SJF_wt/n);
getch();
}
int sort()
{
int t,i,j; for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(bt[i]>bt[j])
{
swap(&bt[j],&bt[i]);
swap(&p[j],&p[i]);
}
}
}
return 0;
}
int swap(int *a, int *b)
{
int t;
t = *a;
*a = *b;
*b = t;
return 0;
}
int WT_TAT(int *a, int *b)
{
int i; for(i=0;i<n;i++)
{
if(i==0)
tat[i] = bt[i];
else
tat[i] = tat[i-1] + bt[i];
tot_tat=tot_tat+tat[i];
}
*a = tot_tat; wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=wt[i-1]+bt[i-1];
tot_wt = tot_wt+wt[i];
}
*b = tot_wt;
printf("\nPROCESS\t\tBURST TIME\tTURN AROUND TIME\tWAITING TIME");
for(i=0; i<n; i++)
printf("\nprocess[%d]\t\t%d\t\t%d\t\t%d",p[i]+1,bt[i],tat[i],wt[i]);
return 0;
}
RESULT:
Thus the program to implement the SJF (Shortest Job First) CPU scheduling Algorithm was written,
executed and the output was verified successfully.
c. FCFS
AIM:
To write a program to implement the FCFS (First Come First Serve) CPU scheduling Algorithm
ALGORITHM:
1. START the program
2. Get the number of processors
3. Get the Burst time of each processors
4. Calculation of Turn Around Time and Waiting Time
a) tot_TAT = tot_TAT + pre_TAT
b) avg_TAT = tot_TAT/num_of_proc
c) tot_WT = tot_WT + pre_WT + PRE_BT
d) avg_WT = tot_WT/num_of_proc
5. Display the result
6. STOP the program
#include<stdio.h>
#include<conio.h>
int p[30],bt[30],tot_tat=0,wt[30],n,tot_wt=0,tat[30],FCFS_wt=0,FCFS_tat=0;
float awt,avg_tat,avg_wt;
void main()
{
int i;
clrscr();
printf("\nEnter the no.of processes \n");
scanf("%d",&n);
printf("Enter burst time for each process\n");
for(i=0;i<n;i++)
{
scanf("%d",&bt[i]);
p[i] = i;
}
printf("\n FCFS Algorithm \n");
WT_TAT(&FCFS_tat,&FCFS_wt);
printf("\n\nTotal Turn around Time:%d",FCFS_tat);
printf("\nAverage Turn around Time :%d ", FCFS_tat/n); printf("\nTotal Waiting Time:%d",FCFS_wt);
printf("\nTotal avg. Waiting Time:%d",FCFS_wt/n);
getch();
}
int WT_TAT(int *a, int *b)
{
int i; for(i=0;i<n;i++)
{
if(i==0)
tat[i] = bt[i];
else
tat[i] = tat[i-1] + bt[i];
tot_tat=tot_tat+tat[i];
}
*a = tot_tat; wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=wt[i-1]+bt[i-1];
tot_wt = tot_wt+wt[i];
}
*b = tot_wt;
printf("\nPROCESS\t\tBURST TIME\tTURN AROUND TIME\tWAITING TIME");
for(i=0; i<n; i++)
printf("\nprocess[%d]\t\t%d\t\t%d\t\t%d",p[i],bt[i],tat[i],wt[i]);
return 0;
}
OUTPUT: (FCFS Scheduling Algorithm)
FCFS Algorithm
RESULT:
Thus the program to implement the FCFS (First Come First Serve) CPU scheduling Algorithm was
written, executed and the output was verified successfully.
d.Priority
AIM:
To write a program to implement the Priority CPU scheduling Algorithm
ALGORITHM:
#include<stdio.h>
#include<conio.h>
int p[30],bt[30],tot_tat=0,pr[30],wt[30],n,tot_wt=0,tat[30],PR_wt=0,PR_tat=0;
float awt,avg_tat,avg_wt;
void main()
{
int i;
clrscr();
printf("\nEnter the no.of processes \n"); scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Enter burst time and priority of process[%d]:",i+1); scanf("%d%d",&bt[i],&pr[i]);
p[i] = i;
}
sort();
WT_TA T(& PR_ tat,& PR_ wt);
printf("\n\nTotal Turn around Time:%d",PR_tat); printf("\nAverage Turn around Time :%d ", PR_tat/n);
printf("\nTotal Waiting Time:%d",PR_wt); printf("\nTotal avg. Waiting Time:%d",PR_wt/n);
getch();
}
int sort()
{
int t,i,j,t2,t1; for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(pr[i]>pr[j])
{
swap(&bt[j],&bt[i]);
swap(&p[j],&p[i]);
swap(&pr[j],&pr[i]);
}
}
}
return 0;
}
int swap(int *a, int *b)
{
int t;
t = *a; *a = *b; *b = t;
return 0;
}
int WT_TAT(int *a, int *b)
{
int i;
for(i=0;i<n;i++)
{
if(i==0)
tat[i] = bt[i];
else
tat[i] = tat[i-1] + bt[i];
tot_tat=tot_tat+tat[i];
}
*a = tot_tat;
wt[0]=0;
for(i=1;i<n;i++)
{
wt[i]=wt[i-1]+bt[i-1];
tot_wt = tot_wt+wt[i];
}
*b = tot_wt;
printf("\nPROCESS\t\tBURST TIME\tPRIORITY\tTURN AROUND TIME\tWAITING TIME");
for(i=0; i<n; i++) printf("\nprocess[%d]\t\t%d\t\t%d\t\t%d\t\t%d",p[i]+1,bt[i],pr[i],tat[i],wt[i]);
return 0;
}
RESULT:
Thus the program to implement the priority CPU scheduling Algorithm was written, executed and the
output was verified successfully.
AIM:
To implement the Interprocess communication using shared memory.
ALGORITHM:
PROGRAM:
Shared1.c:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#define SHMSZ 27
main()
{
char c;
int shmid;
key_t key; char *shm, *s; key = 5678;
if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) { perror("shmget");
exit(1);
}
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1)
{ perror("shmat");
exit(1);
}}
Shared2.c
OUTPUT:
Abcdefghijklmnopqrstuvwxyz
RESULT:
Thus the program has been executed successfully and the output is verified.
5.Implementation of semaphore
Date:
Aim
To synchronize producer and consumer processes using semaphore.
Semaphores
A semaphore is a counter used to synchronize access to a shared data amongst
multiple processes.
To obtain a shared resource, the process should:
o Test the semaphore that controls the resource.
o If value is positive, it gains access and decrements value of semaphore.
o If value is zero, the process goes to sleep and awakes when value is > 0.
When a process relinquishes resource, it increments the value of semaphore by 1.
Producer-Consumer problem
A producer process produces information to be consumed by a consumer process
A producer can produce one item while the consumer is consuming another one.
With bounded-buffer size, consumer must wait if buffer is empty, whereas
producer must wait if buffer is full.
The buffer can be implemented using any IPC facility.
Algorithm
1. Create a shared memory segment BUFSIZE of size 1 and attach it.
2. Obtain semaphore id for variables empty, mutex and full using semget function.
3. Create semaphore for empty, mutex and full as follows:
a. Declare semun, a union of specific commands.
b. The initial values are: 1 for mutex, N for empty and 0 for full
c. Use semctl function with SETVAL command
4. Create a child process using fork system call.
a. Make the parent process to be the producer
b. Make the child process to the consumer
5. The producer produces 5 items as follows:
a. Call wait operation on semaphores empty and mutex using semop function.
b. Gain access to buffer and produce data for consumption
c. Call signal operation on semaphores mutex and full using semop function.
6. The consumer consumes 5 items as follows:
a. Call wait operation on semaphores full and mutex using semop function.
b. Gain access to buffer and consume the available data.
c. Call signal operation on semaphores mutex and empty using semop function.
7. Remove shared memory from the system using shmctl with IPC_RMID argument
8. Stop
Program
#define N 5
#define BUFSIZE 1
#define PERMS 0666
int *buffer;
int nextp = 0, nextc = 0;
int mutex, full, empty; /* semaphore variables */
void producer()
{
int data; if(nextp == N)
nextp = 0;
printf("Enter data for producer to produce : "); scanf("%d",(buffer + nextp));
nextp++;
}
void consumer()
{
int g; if(nextc ==
N)
nextc = 0;
g = *(buffer + nextc++); printf("\nConsumer consumes data
%d", g);
}
s.val = initval;
if((semval = semctl(semid, 0, SETVAL, s)) < 0) printf("\nError in executing
semctl");
}
main()
{
int shmid, i; pid_t
pid;
sem_create(mutex, 1);
sem_create(empty, N);
sem_create(full, 0);
$ gcc pcsem.c
$ ./a.out
Enter data for producer to produce : 5
Result
Thus synchronization between producer and consumer process for access
to a shared memory segment is implemented.
ALGORITHM:
1. start the program
2. Get the required value
3. Check the condition block[p]=0 and eun[p]=0
4. Check the value is greater than or equal to 0
5. If it is fail deadlock will occur
else
6. If m=0,res reg[p][k]=newreg[k]
deadlock will not occur
7. Stop the program.
PROGRAM:
#include<stdio.h>
#include<conio.h>
void main()
{
int n,r,i,j,k,p,u=0,s=0,m;
int block[10],run[10],active[10],newreq[10];
int max[10][10],resalloc[10][10],resreq[10][10];
int totalloc[10],totext[10],simalloc[10];
clrscr();
printf("Enter the no of processes:");
scanf("%d",&n);
printf("Enter the no of resource classes:");
scanf("%d",&r);
printf("Enter the total existed resource in each class:");
for(k=1;k<=r;k++)
scanf("%d",&totext[k]);
printf("Enter the allocated resources:");
for(i=1;i<=n;i++)
for(k=1;k<=r;k++)
scanf("%d",&resalloc);
printf("Enter the process making the new request:");
scanf("%d",&p);
printf("Enter the requested resource:");
for(k=1;k<=r;k++)
scanf("%d",&newreq[k]);
printf("Enter the processes which are n blocked or running:");
for(i=1;i<=n;i++)
{
if(i!=p)
{
printf("process %d:\n",i);
scanf("%d%d",&block[i],&run[i]);
}
}
block[p]=0;
run[p]=0;
for(k=1;k<=r;k++)
{
j=0;
for(i=1;i<=n;i++)
{
totalloc[k]=j+resalloc[i][k];
j=totalloc[k];
}
}
for(i=1;i<=n;i++)
{
if(block[i]==1||run[i]==1)
active[i]=1;
else
active[i]=0;
}
for(k=1;k<=r;k++)
{
resalloc[p][k]+=newreq[k];
totalloc[k]+=newreq[k];
}
for(k=1;k<=r;k++)
{
if(totext[k]-totalloc[k]<0)
{
u=1;break;
}
}
if(u==0)
{
for(k=1;k<=r;k++)
simalloc[k]=totalloc[k];
for(s=1;s<=n;s++)
for(i=1;i<=n;i++)
{
if(active[i]==1)
{
j=0;
for(k=1;k<=r;k++)
{
if((totext[k]-simalloc[k])<(max[i][k]-resalloc[i][k]))
{
j=1;break;
}
}
}
if(j==0)
{
active[i]=0;
for(k=1;k<=r;k++)
simalloc[k]=resalloc[i][k];
}
}
m=0;
for(k=1;k<=r;k++)
resreq[p][k]=newreq[k];
printf("Deadlock willn't occur");
}
else
{
for(k=1;k<=r;k++)
{
resalloc[p][k]=newreq[k];
totalloc[k]=newreq[k];
}
printf("Deadlock will occur");
}
getch();
}
OUTPUT:
Input:
Enter the no of resources: 4
Enter the no of resource classes: 3
Enter the total existed resources in each class: 3 2 2
Enter the allocated resources: 1 0 0 5 1 1 2 1 1 0 0 2
Enter the process making the new request: 2
Enter the requested resource: 1 1 2
Enter the processes which are n blocked or running:
Process 1: 1 2
Process 3: 1 0
Process 4: 1 0
Output:
Deadlock will occur
RESULT:
Thus the program has been executed successfully and the output is verified.
ALGORITHM:
PROGRAM:
#include<stdio.h>
#include<conio.h>
void main()
{
int found,flag,l,p[4][5],tp,tr,c[4][5],i,j,k=1,m[5],r[5],a[5],temp[5],sum=0;
clrscr();
printf("Enter total no of processes");
scanf("%d",&tp);
printf("Enter total no of resources");
scanf("%d",&tr);
printf("Enter claim (Max. Need) matrix\n");
for(i=1;i<=tp;i++)
{
printf("process %d:\n",i);
for(j=1;j<=tr;j++)
scanf("%d",&c[i][j]);
}
printf("Enter allocation matrix\n");
for(i=1;i<=tp;i++)
{
printf("process %d:\n",i);
for(j=1;j<=tr;j++)
scanf("%d",&p[i][j]);
}
printf("Enter resource vector (Total resources):\n");
for(i=1;i<=tr;i++)
{
scanf("%d",&r[i]);
}
printf("Enter availability vector (available resources):\n");
for(i=1;i<=tr;i++)
{
scanf("%d",&a[i]);
temp[i]=a[i];
}
for(i=1;i<=tp;i++)
{
sum=0;
for(j=1;j<=tr;j++)
{
sum+=p[i][j];
}
if(sum==0)
{
m[k]=i; k++;
}
}
for(i=1;i<=tp;i++)
{
for(l=1;l<=tr;j++)
if(c[i][j]<temp[j])
{
flag=0;
break;
}
}
if(flag==1)
{
m[k]=i;
k++;
for(j=1;j<=tr;j++)
temp[j]+=p[i][j];
}
//}
printf("deadlock causing processes are:");
for(j=1;j<=tp;j++)
{
found=0;
for(i=1;i<k;i++)
{ if(j==m[i])
found=1;
}
if(found==0)
printf("%d\t",j);
}
getch();
}
OUTPUT:
Enter total no. of processes : 4
Enter total no. of resources : 5
Enter claim (Max. Need) matrix : 0 1 0 0 1
00101
00001
10101
Enter allocation matrix : 1 0 1 1 0
11000
00010
00000
Enter resource vector (Total resources) : 2 1 1 2 1
Enter availability vector (available resources) : 0 0 0 0 1
deadlock causing processes are : 2 3
RESULT:
Thus the program has been executed successfully and the output is verified.