Os Lab Practical
Os Lab Practical
Os Lab Practical
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
pid_t forkStatus;
forkStatus = fork();
/* Child... */
if (forkStatus == 0) {
printf("Child is running, processing.\n");
sleep(5);
printf("Child is done, exiting.\n");
/* Parent... */
} else if (forkStatus != -1) {
printf("Parent is waiting...\n");
wait(NULL);
printf("Parent is exiting...\n");
} else {
perror("Error while calling the fork function");
return 0;
Output :
Parent is waiting...
Child is running, processing.
Child is done, exiting.
Parent is exiting...
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
int main()
{
int fd[2];
char buf1[25]="just a test\n";
char buf2[50];
fd[0]=open("file1",O_RDWR);
fd[1]=open("file2",O_RDWR);
write(fd[0],buf1,strlen(buf1));
printf("\n Enter the text now.....");
scanf("\n %s",buf1);
printf("\n cat file1 is \n hai");
write(fd[0],buf1,strlen(buf1));
lseek(fd[0],SEEK_SET,0);
read(fd[0],buf2,sizeof(buf1));
write(fd[1],buf2,sizeof(buf2));
close(fd[0]);
printf("\n");
return 0;
}
Output:
cat file1 is
cat
IPC_STAT − Copies information of the current values of each member of struct msqid_ds to the passed
structure pointed by buf. This command requires read permission on the message queue.
IPC_SET − Sets the user ID, group ID of the owner, permissions etc pointed to by structure buf.
IPC_INFO − Returns information about the message queue limits and parameters in the structure
pointed by buf, which is of type struct msginfo
MSG_INFO − Returns an msginfo structure containing information about the consumed system
resources by the message queue.
The third argument, buf, is a pointer to the message queue structure named struct msqid_ds. The
values of this structure would be used for either set or get as per cmd.
This call would return the value depending on the passed command. Success of IPC_INFO and
MSG_INFO or MSG_STAT returns the index or identifier of the message queue or 0 for other operations
and -1 in case of failure. To know the cause of failure, check with errno variable or perror() function.
Having seen the basic information and system calls with regard to message queues, now it is time to
check with a program.
Step 1 − Create two processes, one is for sending into message queue (msgq_send.c) and another is for
retrieving from the message queue (msgq_recv.c)
Step 2 − Creating the key, using ftok() function. For this, initially file msgq.txt is created to get a unique
key.
To simplify, we are not using the message type for this sample. Also, one process is writing into the
queue and another process is reading from the queue. This can be extended as needed i.e., ideally one
process would write into the queue and multiple processes read from the queue.
/* Filename: msgq_send.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main(void) {
struct my_msgbuf buf;
int msqid;
int len;
key_t key;
system("touch msgq.txt");
Following is the code from message receiving process (retrieving message from queue) – File:
msgq_recv.c
/* Filename: msgq_recv.c */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int main(void) {
struct my_msgbuf buf;
int msqid;
int toend;
key_t key;
if ((key = ftok("msgq.txt", 'B')) == -1) {
perror("ftok");
exit(1);
}
A single-tasking system can only run one program at a time, while a multi-tasking
operating system allows more than one program to be running in concurrency. This is achieved by
time-sharing, dividing the available processor time between multiple processes that are each
interrupted repeatedly in time slices by a task-scheduling subsystem of the operating system.
Process Scheduling
Processes are the Small Programs those are executed by the user according to their Request.
CPU Executes all the Process according to Some Rules or Some Schedule. Scheduling ist hat in
which each process have Some Amount of Time of CPU. Scheduling Provides Time of CPU to the
Each Process.
The First Come First Served (FCFS) Scheduling Algorithm is the simplest one. In this
algorithm the set of ready processes is managed as FIFO (first-in-first-out) Queue. The processes
are serviced by the CPU until completion in order of their entering in the FIFO queue.
A process once allocated the CPU keeps it until releasing the CPU either by terminating or
requesting I/O. For example, interrupted process is allowed to continujre running after interrupt
handling is done with.
#include<stdio.h>
struct process
{
int pid; int bt; int wt,tt;
}p[10];
int main()
{
int i,n
float totwt,tottt,avg1,avg2;
clrscr();
printf("enter the no of process \n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
p[i].pid=i;
printf("enter the burst time n");
scanf("%d",&p[i].bt);
}
p[1].wt=0;
p[1].tt=p[1].bt+p[1].wt;
i=2;
while(i<=n)
{
p[i].wt=p[i-1].bt+p[i-1].wt;
p[i].tt=p[i].bt+p[i].wt;
i ++;
}
i=1;
p[i].wt=p[i-1].bt+p[i-1].wt;
p[i].tt=p[i].bt+p[i].wt;
totwt=tottt=0;
printf("\n processid \t bt\t wt\t tt\n");
while(i<=n)
{
printf("\n\t%d \t%d \t%d \t%d",p[i].pid,p[i].bt,p[i].wt,p[i].tt); totwt=p[i].wt+totwt;
tottt=p[i].tt+tottt;
i++;
}
avg1=totwt/n; avg2=tottt/n; printf("\navg1=%f \t avg2=%f\t",avg1,avg2);
getch();
return 0;
}
Process sid bt wt tt
1 2 0 2
2 4 2 6
3 6 6 12
avg1=2.66 avg2=6.22
RESULT:
Thus the FIFO process scheduling program was executed and verified successfully.
#include<stdio.h>
#include<conio.h>
struct process
{
int main()
{
int i,j,n,totwt,tottt;
float avg1,avg2;
clrscr();
printf("\nEnter the number of process:\t");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
p[i].pid=i;
printf("\nEnter the burst time:\t");
scanf("%d",&p[i].bt);
}
for(i=1;i<n;i++)
{
for(j=i+1;j<=n;j++)
{
if(p[i].bt>p[j].bt)
{
temp.pid=p[i].pid;
p[i].pid=p[j].pid;
p[j].pid=temp.pid;
temp.bt=p[i].bt;p[i].bt=p[j].bt;
p[j].bt=temp.bt;
}
}
}
p[1].wt=0;
p[1].tt=p[1].bt+p[1].wt;
i=2;
while(i<=n)
{
p[i].wt=p[i-1].bt+p[i-1].wt;
p[i].tt=p[i].bt+p[i].wt;
i++;
}
OUTPUT:
VG1=2.000000 AVG2=6.000000
RESULT:
#include<stdio.h>
int main()
{
int bt[20],p[20],wt[20],tat[20],pr[20],i,j,n,total=0,pos,temp,avg_wt,avg_tat;
printf("Enter Total Number of Process:");
scanf("%d",&n);
//sorting burst time, priority and process number in ascending order using selection sort
for(i=0;i<n;i++)
{
pos=i;
for(j=i+1;j<n;j++)
{
if(pr[j]<pr[pos])
pos=j;
}
temp=pr[i];
pr[i]=pr[pos];
pr[pos]=temp;
temp=bt[i];
bt[i]=bt[pos];
bt[pos]=temp;
temp=p[i];
p[i]=p[pos];
p[pos]=temp;
}
total+=wt[i];
DEPARTMENT OF COMPUTER SCIENCE 22
}
return 0;
}
OUTPUT:
process to bt wt tt
1 4 0 4 4
2 6 4 10 14
3 2 10 12 22
avg1=4.22 avg2=8.666
RESULT:
Thus the priority scheduling program was executed and verified successfully
#include<stdio.h>
#include<conio.h>
struct process
{
int pid,bt,tt,wt;
};
int main()
{
struct process x[10],p[30];
int i,j,k,tot=0,m,n;
float wttime=0.0,tottime=0.0,a1,a2;
clrscr();
printf("\nEnter the number of process:\t");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
x[i].pid=i;
printf("\nEnter the Burst Time:\t");
scanf("%d",&x[i].bt);
tot=tot+x[i].bt;
}
printf("\nTotal Burst Time:\t%d",tot);
p[0].tt=0;
k=1;
printf("\nEnter the Time Slice:\t");
scanf("%d",&m);
for(j=1;j<=tot;j++)
{
for(i=1;i<=n;i++)
{
if(x[i].bt !=0)
{
p[k].pid=i;
if(x[i].bt-m<0)
{
p[k].wt=p[k-1].tt;
p[k].bt=x[i].bt;
p[k].tt=p[k].wt+x[i].bt;
x[i].bt=0;
k++;
}
else
{
p[k].wt=p[k-1].tt;
OUTPUT:
process id wt tt
1 0 2
2 2 4
3 4 6
1 6 7
process id wt tt
2 7 9
3 9 11
2 11 12
3 12 14
3 14 15
#include<stdio.h>
#include<unistd.h>
int main() {
int pipefds[2];
int returnstatus;
int pid;
char writemessages[2][20]={"Hi", "Hello"};
char readmessage[20];
returnstatus = pipe(pipefds);
if (returnstatus == -1) {
printf("Unable to create pipe\n");
return 1;
}
pid = fork();
// Child process
if (pid == 0) {
read(pipefds[0], readmessage, sizeof(readmessage));
printf("Child Process - Reading from pipe – Message 1 is %s\n", readmessage);
read(pipefds[0], readmessage, sizeof(readmessage));
printf("Child Process - Reading from pipe – Message 2 is %s\n", readmessage);
} else { //Parent process
printf("Parent Process - Writing to pipe - Message 1 is %s\n", writemessages[0]);
write(pipefds[1], writemessages[0], sizeof(writemessages[0]));
printf("Parent Process - Writing to pipe - Message 2 is %s\n", writemessages[1]);
write(pipefds[1], writemessages[1], sizeof(writemessages[1]));
}
return 0;
}
Execution
Parent Process - Writing to pipe - Message 1 is Hi
Parent Process - Writing to pipe - Message 2 is Hello
Child Process - Reading from pipe – Message 1 is Hi
Child Process - Reading from pipe – Message 2 is Hello
Memory Management is one of the services provided by OS which is needed for Optimized
memory usage of the available memory in a Computer System.
1. First Fit
2. Best Fit
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.
a) Best-fit
#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;
}
}
INPUT
Enter the number of blocks: 3
Enter the number of files: 2
OUTPUT
b) 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,highest=0;
static int bf[max],ff[max];
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)
{
ff[i]=j;
highest=temp;
}
}
}
frag[i]=highest;
bf[ff[i]]=1;
highest=0;
}
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();
}
OUTPUT
File No File Size Block No Block Size Fragment
1 1 3 7 6
2 4 1 5 1
#include<stdio.h>
void main()
{
int buffer[10], bufsize, in, out, produce, consume, choice=0; in = 0;
out = 0;
bufsize = 10;
while(choice !=3)
{
printf("\n1. Produce \t 2. Consume \t3. Exit");
printf("\nEnter your choice: =");
scanf("%d", &choice);
switch(choice)
{
case 1:
if((in+1)%bufsize==out)
printf("\nBuffer is Full");
else
{
printf("\nEnter the value: ");
scanf("%d", &produce);
buffer[in] = produce;
in = (in+1)%bufsize;
}
break;
case 2:
if(in == out)
printf("\nBuffer is Empty");
else
{
consume = buffer[out];
printf("\nThe consumed value is %d", consume); out = (out+1)%bufsize;
}
break;
}
}
}
RESULT:
Thus the producer consumer program was executed and verified successfully
Output
Enter a number : 3
Enter a number: 4
24
Enter a number : 5
120
Output :