OS Record
OS Record
PROGRAM: 1(A)
Here, a program to copy the contents of one file into another is used to demonstrate the
usage of file related system calls.
Syntax:
open()
#include<fcntl.h>
int open(const char *path,int oflag);
close()
#include <unistd.h>
int close(int fildes);
read()
#include<sys/types.h>
size_t read(int fildes,void *buf,size_t nbyte);
write()
#include<sys/types.h>
size_t write(int fildes, const void *buf, size_t nbyte);
Algorithm:
1: open file1 in read mode.
2: open or create file2 and open it in write mode
3: Read data from file1 into a buffer.
4: Write data to file2 from buffer.
5: Close the files.
6: Open file2 for Read only
7: Read data from file into buffer.
8: Display buffer data to standard output
9: Close the file.
Program:
Read():
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#define BUFSIZE 1024
int main()
{
int fd1,n;
char buf[BUFSIZE];
fd1=open("[Link]",O_RDONLY);
if(fd1<0)
{
perror("Error");
exit(1);
}
n=read(fd1,buf,BUFSIZE);
if(n==-1)
{
perror("Error");
exit(1);
}
printf("n=%d",n);
close(fd1);
}
Output:
Open():
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
int fd1=open("[Link]", O_RDONLY);
int fd2=open("[Link]", O_RDONLY);
if((fd1||fd2)==-1)
{
perror("Error in Opening");
exit(1);
}
printf("\nfd1=%d\tfd2=%d",fd1,fd2);
close(fd1);
close(fd2);
}
Output:
Write():
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd1,fd2,n;
char buf[25];
fd1=open("[Link]",O_RDONLY);
fd2=open("[Link]",O_WRONLY/O_APPEND);
while((n=read(fd1,buf,20))!=0)
{
write(fd2,buf,n);
}
close(fd1);
close(fd2);
}
Output:
Copy():
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/stat.h>
int main(int argc,char* argv[])
{
int fd1,fd2,n;
char buf[25];
fd1=open(argv[1], O_RDONLY);
fd2=open(argv[2], O_WRONLY|O_CREAT,0644);
if((fd1<0||fd2)<0)
{
printf("Error");
exit(1);
}
while(1)
{
int n=read(fd1,buf,1);
write(fd2,buf,1);
if(n<=0)
break;
}
close(fd1);
close(fd2);
fd2=open(argv[2], O_RDONLY);
if(fd2<0)
{
printf("Error");
exit(1);
}
while(1)
{
n=read(fd2,buf,1);
if(n<=0)
break;
write(1,buf,1);
}
close(fd2);
}
Output:
Operating Systems Lab
PROGRAM: 1(B)
AIM: Program to reposition the file offset on Linux using lseek( ) system call
Problem Definition: To write the program to implement the system call lseek( ).
Problem Description: lseek() system call is used to reposition the file offset.
Syntax:
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
This function return lseek() returns the resulting offset location as measured in bytes from the
beginning of the file. On error, the value (off_t) -1 is returned
lseek() repositions the file offset of the open file description associated with the file descriptor
fd to the argument offset according to the directive whence as follows:
SEEK_SET
The file offset is set to offset bytes.
SEEK_CUR
The file offset is set to its current location plus offset bytes.
SEEK_END
The file offset is set to the size of the file plus offset bytes.
Algorithm:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
int main()
{
int fd;
char buf[20];
fd=open("[Link]",O_RDONLY);
if(fd<0)
{
printf("Error");
exit(1);
}
read(fd,buf,10);
write(1,buf,10);
printf("\n");
lseek(fd,10,SEEK_SET);
read(fd,buf,10);
write(1,buf,10);
printf("\n");
close(fd);
}
Output:
lseek() with SEEK_CUR:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
int main()
{
int fd;
char buf[20];
fd=open("[Link]",O_RDONLY);
if(fd<0)
{
printf("Error");
exit(1);
}
read(fd,buf,10);
write(1,buf,10);
printf("\n");
lseek(fd,10,SEEK_CUR);
read(fd,buf,10);
write(1,buf,10);
printf("\n");
close(fd);
}
Output:
lseek() with SEEK_END:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
int main()
{
int fd;
char buf[20];
fd=open("[Link]",O_RDWR);
if(fd<0)
{
printf("Error");
exit(1);
}
read(fd,buf,10);
write(1,buf,10);
printf("\n");
lseek(fd,-11,SEEK_END);
read(fd,buf,10);
write(1,buf,10);
close(fd);
}
Output:
Operating Systems Lab
PROGRAM: 1(C)
AIM: Program to get the attributes of a file on Linux using stat( ) system call
Problem Definition: To write the program to implement the system call stat( ).
Problem Description: stat() system call is used to get file attributes.
Syntax:
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *pathname, struct stat *statbuf);
This function return information about a file, in the buffer pointed to by statbuf
stat returns 0 if successful and –1 otherwise
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */ }
Algorithm:
Stat:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#include<time.h>
int main(int argc, char* argv[])
{
int fd;
struct stat buf;
fd = stat(argv[1],&buf);
if(fd<0)
{
perror("Error");
exit(1);
}
printf("Inode no=%d\n",buf.st_ino);
printf("user id=%d\n",buf.st_uid);
printf("grp id=%d\n",buf.st_gid);
printf("No of links=%d\n",buf.st_nlink);
printf("size=%d\n",buf.st_size);
printf("Last status change =%s",ctime(&buf.st_ctime));
printf("Last file accessed =%s",ctime(&buf.st_atime));
printf("Last file modified =%s",ctime(&buf.st_mtime));
Output:
Operating Systems Lab
PROGRAM: 2(A)
AIM: Program to demonstrate the usage of file related system calls
Syntax:
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
On success, the PID of the child process is returned in the parent, and 0 is returned in the child.
On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
Syntax:#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus);
On success returns the process ID of the terminated child;
On error, -1 is returned
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was
interrupted by a signal handler
fork() creates a new process by duplicating the calling process. The new process is referred to as the
child process. The calling process is referred to as the parent process.
The child process and the parent process run in separate memory spaces. At the time of fork() both
memory spaces have the same content. Memory writes, file mappings, and unmappings performed
by one of the processes do not affect the other.
After fork returns, the parent process and child process now have different PIDs. At this
point, there are two processes with practically identical constitute, and they both continue execution
at the statement following fork(). To be able to distinguish between the parent and the child process,
fork returns with two values: Zero in the child process. The PID of the child is returned in the
parent process.
System Calls Used:
fork ( ) is used to create new process. The new process consists of a copy of the addressspace of
the original process. The value of process id for the child process is zero, whereas the value of
process id for the parent is an integer value greater than zero.
The wait() system call suspends execution of the calling thread until one of its children
terminates. The parent waits for the child process to complete using the wait system call. The
wait system call returns the process identifier of a terminated child, so that the parent can tell
which of its possibly many children has terminated.
sleep() causes the calling thread to sleep either until the number of real-time seconds specified in
seconds have elapsed or until a signal arrives which is not ignored.
.
Program:
Fork:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
int pid;
printf("demo of fork()");
pid=fork();
//printf("demo of fork()");
if(pid<0)
{
exit(1);
}
else if(pid==0)
{
printf("I am a child process\n");
printf("my id=%d\n",getpid());
printf("my parent id=%d\n",getppid());
}
else
{
printf("I am a parent process\n");
printf("my id=%d\n",getpid());
printf("my parent id=%d\n",getppid());
printf("my child id=%d\n",pid);
}
}
Output:
Operating Systems Lab
PROGRAM: 2(B)
AIM: Program to demonstrate orphan process
Hence to create such a process a child is created first and it is made to sleep for some amount of
time. This allows the parent to complete its execution first, thus resulting in the creation of an
orphan process.
Syntax:#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
getpid() returns the process ID (PID) of the calling process.
getppid() returns the process ID of the parent of the calling process. This will be either the ID of
the process that created this process using fork(), or, if that process has already terminated, the ID
of the process to which this process has been reparented (init(1)).
Algorithm:
1. Create a child process
2. Child process is suspended for some time so that the parent process terminates to
demonstrate an orphan process
3. The init process becomes the parent of the orphan process
Program:
Orphan:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
int pid;
printf("demo of fork()");
pid=fork();
//printf("demo of fork()");
if(pid<0)
{
exit(1);
}
else if(pid==0)
{
sleep(2);
printf("I am a child process\n");
printf("my id=%d\n",getpid());
printf("my parent id=%d\n",getppid());
}
else
{
printf("I am a parent process\n");
printf("my id=%d\n",getpid());
printf("my parent id=%d\n",getppid());
printf("my child id=%d\n",pid);
}
}
Output:
Operating Systems Lab
PROGRAM: 2(C)
AIM: Program to demonstrate zombie process
∙ In most cases, under normal system operation zombies are immediately waited on by their
parent.
∙ Processes that stay zombies for a long time are generally an error and cause a resource leak.
Hence to create such a process child terminates before the parent does wait on the child and
becomes a zombie process.
Algorithm:
1. Create a child process
2. Parent process is suspended for some time so that the child process terminates to demonstrate
a zombie process
Program:
Zombie:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
int main()
{
int pid;
printf("demo of fork()");
pid=fork();
//printf("demo of fork()");
if(pid<0)
{
exit(1);
}
else if(pid==0)
{
system("ps -l");
printf("I am a child process\n");
printf("my id=%d\n",getpid());
printf("my parent id=%d\n",getppid());
}
else
{
sleep(2);
system("ps -l");
printf("I am a parent process\n");
printf("my id=%d\n",getpid());
printf("my parent id=%d\n",getppid());
printf("my child id=%d\n",pid);
}
}
Output:
Operating Systems Lab
Program: 3(A)
AIM: Program to implement the concept of threads (Single Thread)
Syntax:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)
(void *), void *arg);
The pthread_create() function starts a new thread in the calling process. The new thread starts
execution by invoking start_routine(); arg is passed as the sole argument of start_routine(). The
attr argument points to a pthread_attr_t structure whose contents are used at thread creation time
to determine attributes for the new thread; If attr is NULL, then the thread is created with default
attributes. Before returning, a successful call to pthread_create() stores the ID of the new thread
in the buffer pointed to by thread; this identifier is used to refer to the thread in subsequent calls
to other pthreads functions.
Algorithm:
1: Start the program.
2: Use pthread_create() to create a new thread. Specify the name of the routine within it. 3: Use
pthread_join() to synchronize.
4: Print messages and sleep for random time.
5: Within routine print some messages and sleep. Then use pthread_exit to terminate the thread.
Program:
Thread:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<pthread.h>
void *run();
int main()
{
int i,ret;
pthread_t t;
ret=pthread_create(&t,NULL,run,0);
if(ret==-1)
{
printf("Error");
exit(1);
}
for(i=0;i<=4;i++)
{
printf("Inside Main\n");
sleep(2);
}
}
void *run()
{
int i;
for(i=0;i<=4;i++)
{
printf("Inside Thread\n");
sleep(2);
}
pthread_exit(0);
}
Output:
pthread_join():
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<pthread.h>
void *run();
int main()
{
int i,ret;
pthread_t t;
ret=pthread_create(&t,NULL,run,0);
if(ret==-1)
{
printf("Error");
exit(1);
}
pthread_join(t,0);
for(i=0;i<=4;i++)
{
printf("Inside Main\n");
sleep(2);
}
}
void *run()
{
int i;
for(i=0;i<=4;i++)
{
printf("Inside Thread\n");
sleep(2);
}
pthread_exit(0);
}
Output:
Operating Systems Lab
Program: 3(B)
AIM: Program to implement the concept of multithreading
Syntax:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)
(void *), void *arg);
The pthread_create() function starts a new thread in the calling process. The new thread starts
execution by invoking start_routine(); arg is passed as the sole argument of start_routine(). The
attr argument points to a pthread_attr_t structure whose contents are used at thread creation time
to determine attributes for the new thread; If attr is NULL, then the thread is created with default
attributes. Before returning, a successful call to pthread_create() stores the ID of the new thread
in the buffer pointed to by thread; this identifier is used to refer to the thread in subsequent calls
to other pthreads functions.
Multithreading:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<pthread.h>
void *run1();
void *run2();
void *run3();
int main()
{
int i,ret1,ret2,ret3;
pthread_t t1;
pthread_t t2;
pthread_t t3;
ret1=pthread_create(&t1,NULL,run1,0);
if(ret1==-1)
{
printf("Error");
exit(1);
}
pthread_join(t1,0);
ret2=pthread_create(&t2,NULL,run2,0);
if(ret2==-1)
{
printf("Error");
exit(1);
}
pthread_join(t2,0);
ret3=pthread_create(&t3,NULL,run3,0);
if(ret3==-1)
{
printf("Error");
exit(1);
}
pthread_join(t3,0);
for(i=0;i<=4;i++)
{
printf("Inside Main\n");
sleep(2);
}
}
void *run1()
{
int i;
for(i=0;i<=4;i++)
{
printf("Inside Thread1\n");
sleep(2);
}
pthread_exit(0);
}
void *run2()
{
int i;
for(i=0;i<=4;i++)
{
printf("Inside Thread2\n");
sleep(2);
}
pthread_exit(0);
}
void *run3()
{
int i;
for(i=0;i<5;i++)
{
printf("Inside Thread3\n");
sleep(2);
}
pthread_exit(0);
}
Output:
Operating Systems Lab
Program: 4(A)
AIM: Program to simulate CPU scheduling algorithm for first come first
serve scheduling.
Problem Definition: To write a program to calculate wait time and turnaround time of
processes using non preemptive FCFS algorithm.
Problem Description: Assume all the processes arrive at the same time.
For FCFS scheduling algorithm, read the number of processes/jobs in the system, their CPU
burst times. The scheduling is performed on the basis of arrival time of the processes irrespective
of their other parameters. Each process will be executed according to its arrival time. Calculate
the waiting time and turnaround time of each of the processes accordingly.
Algorithm:
FCFS:
#include<stdio.h>
int main()
{
int
n,i,j,k,l,AT[10]={0},BT[10]={0},CT[10]={0},TAT[10]={0},WT[10]={0};
float totalTAT=0;
float totalWT=0;
printf("Enter no. of Processes:");
scanf("%d",&n);
//AT and BT
for(i=1;i<=n;i++)
{
printf("Enter AT for P[%d]:",i);
scanf("%d",&AT[i]);
printf("Enter BT for P[%d]:",i);
scanf("%d",&BT[i]);
}
//CT
int sum=AT[0];
for(j=1;j<=n;j++)
{
sum=sum+BT[j];
CT[j]=sum;
}
//TAT
for(k=1;k<=n;k++)
{
TAT[k]=CT[k]-AT[k];
totalTAT=totalTAT+TAT[k];
}
//WT
for(k=1;k<=n;k++)
{
WT[k]=TAT[k]-BT[k];
totalWT=totalWT+WT[k];
}
printf("P\tAT\tBT\tCT\tTAT\tWT\n");
for(i=1;i<=n;i++)
{
printf("P%d\t%d\t%d\t%d\t%d\t%d\n",i,AT[i],BT[i],CT[i],TAT[i],WT[i]);
}
printf("Average TAT = %f\n",totalTAT/n);
printf("Average WT = %f\n",totalWT/n);
}
Output:
Operating Systems Lab
Program: 4(B)
AIM: Program to simulate CPU scheduling algorithm for Shortest Job First
Scheduling.
Problem Definition: To write a program to calculate wait time and turnaround time of
processes using non preemptive SJF algorithm.
Problem Description: Assume all the processes arrive at the same time.
For SJF scheduling algorithm, read the number of processes/jobs in the system, their CPU burst
times. Arrange all the jobs in order with respect to their burst times. There may be two jobs in
queue with the same execution time, and then FCFS approach is to be performed. Each process
will be executed according to the length of its burst time. Then calculate the waiting time and
turnaround time of each of the processes accordingly.
Algorithm:
1. Start the program. Get the number of processes and their burst time.
2. Sort the processes according to their burst time. for(i=0; i<n; i++) and within that loop use
another loop for(j=i+1; j<n; j++), if(bt[j]<bt[i]) then use temp to swap i & j. 3. Initialize the
waiting time for first process as 0.
4. Calculate wait time, for(i=1; i<n; i++), which is the sum of current process wait time and burst
time of previous process. wt[i]=wt[i]+bt[i-1].
5. The waiting time of all the processes is summed then average value time is calculated. 6.
Calculate turnaround time, for(i=0; i<n; i++), which is the sum of wait time and burst time of the
process, tat[i]=wt[i]+bt[i].
7. Waiting time and turnaround time of each process and average times are displayed
8. Stop the program
Program:
SJF:
#include<stdio.h>
int main()
{
int
n,i,j,k,T,P[10],AT[10]={0},BT[10]={0},CT[10]={0},TAT[10]={0}
,WT[10]={0};
float totalTAT=0;
float totalWT=0;
printf("Enter no. of Processes:");
scanf("%d",&n);
//AT and BT
for(i=0;i<n;i++)
{
P[i]=i+1;
printf("Enter AT for P[%d]:",i+1);
scanf("%d",&AT[i]);
printf("Enter BT for P[%d]:",i+1);
scanf("%d",&BT[i]);
}
//Sort according to BT
for(i=0;i<n;i++)
{
for(j=0;j<(n-i-1);j++)
{
if(BT[j]>BT[j+1])
{
T=BT[j];
BT[j]=BT[j+1];
BT[j+1]=T;
T=P[j];
P[j]=P[j+1];
P[j+1]=T;
T=AT[j];
AT[j]=AT[j+1];
AT[j+1]=T;
}
}
}
//CT
int sum=AT[0];
for(j=0;j<n;j++)
{
sum=sum+BT[j];
CT[j]=sum;
}
//TAT
for(k=0;k<n;k++)
{
TAT[k]=CT[k]-AT[k];
totalTAT=totalTAT+TAT[k];
}
//WT
for(k=0;k<n;k++)
{
WT[k]=TAT[k]-BT[k];
totalWT=totalWT+WT[k];
}
printf("P\tAT\tBT\tCT\tTAT\tWT\n");
for(i=0;i<n;i++)
{
printf("P%d\t%d\t%d\t%d\t%d\t%d\n",P[i],AT[i],BT[i],
CT[i],TAT[i],WT[i]);
}
printf("Average TAT = %f\n",totalTAT/n);
printf("Average WT = %f\n",totalWT/n);
}
Output:
Operating Systems Lab
Program: 4(C)
AIM: Program to simulate CPU scheduling algorithm for round robin
Scheduling.
Problem Definition: To write a program to calculate wait time and turnaround time of
processes using round robin scheduling algorithm.
Problem Description: Assume all the processes arrive at the same time.
For round robin scheduling algorithm, read the number of processes/jobs in the system, their
CPU burst times, and the size of the time slice. Time slices are assigned to each process in equal
portions and in circular order, handling all processes execution. This allows every process to get
an equal chance. Calculate the waiting time and turnaround time of each of the processes
accordingly.
Algorithm:
1. Start the program. Get the number of process and their burst time.
2. Get Time Slice value.
3. Initialize the remaining time of each process with their burst times.
3. Schedule the processes as
if remaining bursttime > time slice.
Turnaround time is updated.
The remaining burst time of each process is calculated
else update remaining time for that process as 0. And calculate turnaround time. 4.
Calculate wait time as wt[i]=tat[i]-bt[i].
5. The average waiting time for each process and average turnaround times are calculated and
displayed.
6. Stop the program.
Program:
Round Robin:
#include<stdio.h>
int main()
{
int n,BT[10],TAT[10],WT[10],RT[10],c=0,ts=2,t=0;
float totalTAT=0, totalWT=0;
printf("Enter no. of process:");
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
//printf("Enter AT of P%d:",i+1);
//scanf("%d",&AT[i]);
printf("Enter BT of P%d:",i);
scanf("%d",&BT[i]);
}
for(int i=1;i<=n;i++)
RT[i]=BT[i];
while(1)
{
for(int i=1;i<=n;i++)
if(RT[i]>0)
{
if(RT[i]>ts)
{
t+=ts;
RT[i]-=ts;
}
else
{
t+=RT[i];
RT[i]=0;
TAT[i]=t;
c++;
}
}
if(c==n)
{
break;
}
}
for(int i=1;i<=n;i++)
{
WT[i]=TAT[i]-BT[i];
}
for(int i=1;i<=n;i++)
{
totalTAT+=TAT[i];
totalWT+=WT[i];
}
float aWT=totalWT/n;
float aTAT=totalTAT/n;
printf("\nP\tBT\tTAT\tWT\n\n");
for(int i=1;i<=n;i++)
{
printf("P%d\t%d\t%d\t%d\n",i,BT[i],TAT[i],WT[i]);
}
printf("\nAverage TAT=%f",aTAT);
printf("\nAverage WT=%f",aWT);
printf("\n");
}
Output:
Operating Systems Lab
Program: 5(A)
AIM: Program to demonstrate IPC using Unnamed Pipes
Problem Definition: To implement two-process communication through Echo server
application using unnamed pipes.
Problem Description: One of the mechanisms that allow related-processes to communicate
is the pipe. A pipe is a one-way mechanism that allows two related processes (i.e. one is an
ancestor of the other) to send a byte stream from one of them to the other one. The system
assures us of one thing: The order in which data is written to the pipe is the same order as that in
which data is read from the pipe. The system also assures that data won't get lost in the middle,
unless one of the processes (the sender or the receiver) exits prematurely. An echo server is
usually an application which is used to test if the connection between a client and a server is
successful. It consists of a server which sends back whatever text the client sends. The program
shows communication between 2 processes using the IPC mechanism – pipes.
Syntax:
#include <unistd.h>
int pipe (int fd[2]);
Return: 0 on success
-1 on errors
fd[0] is set up for reading and fd[1] is set up for writing. The first element in the array (element
0) is set up and opened for reading while the second element (element 1) is setup and opened for
writing. Visually speaking, the output of first becomes the input for second. Once again, all the
data travelling through pipe moves through the kernel.
Algorithm:
Unnamed Pipe:
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int a[2],pid;
char str[20],buf[20];
pipe(a);
pid=fork();
if(pid<0)
{
exit(1);
}
//child
if(pid==0)
{
strcpy(str,"Demo of Pipes\n");
write(a[1],str,strlen(str)+1);
printf("Child Process writes in pipe\n");
}
//parent
else
{
read(a[0],buf,sizeof(buf));
printf("Parent Process has read %s\n",buf);
}
}
Output:
Operating Systems Lab
Program: 5(B)
AIM: Program to demonstrate IPC using Named Pipes
Problem Definition: To implement inter-process communication through Named pipes
(fifo).
Problem Description: One of the mechanisms that allow processes to communicate is the
named pipe (fifo). A FIFO special file (a named pipe) is similar to a pipe, except that it is
accessed as part of the filesystem. It can be opened by multiple processes for reading or writing.
When processes are exchanging data via the FIFO, the kernel passes all data internally without
writing it to the filesystem. fifo is a two-way mechanism that allows two unrelated processes to
send/ receive a byte stream between them. The program shows communication between 2
processes using the IPC mechanism – fifo.
Syntax:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
Return: 0 on success
-1 on errors
Once a FIFO special file is created, any process can open it for reading or writing, in the same
way as an ordinary file. However, it has to be open at both ends simultaneously before you can
proceed to do any input or output operations on it.
Algorithm:
Named Pipe:
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int a[2],b[2],pid;
char str[20],buf1[20],buf2[20];
pipe(a);
pipe(b);
pid=fork();
if(pid<0)
{
exit(1);
}
//child
if(pid==0)
{
strcpy(str,"Demo of Pipes\n");
write(a[1],str,strlen(str)+1);
printf("Child Process writes in pipe\n");
read(b[0],buf2,sizeof(buf2));
printf("Child Process has read %s\n",buf2);
}
//parent
else
{
sleep(1);
read(a[0],buf1,sizeof(buf1));
printf("Parent Process has read %s\n",buf1);
//strcat(buf1," MD");
write(b[1],buf1,strlen(buf1)+1);
printf("Parent Process writes in pipe\n");
}
}
Output:
Operating Systems Lab
Program: 5(C)
AIM: Program to demonstrate IPC using message queues
Problem Definition: To implement two-process communication through Echo server
application using message queues.
Problem Description: In message queue, a mail box is created. The OS should read and
write program. A message queue is created and owned by one process. A message queue is
created by a msgget call with the following syntax
msgget( key, flag )
The OS maintains an array of message queues and their keys. The first msgget call results in
creation of new message queue.
The position of the message queue in the system array (called the message queue id ) is returned
by the msgget call. This id’s are used in a send or receive call.
The send and receive calls have the following syntax:
msgsnd( msgqid, msg, count, flag );
msgrcv( msgqid, msg-struct-ptr, maxcount, type, flag );
The count and flag parameters of msgsnd specify number of bytes in a message and the actions it
should take if sufficient space is not available in message queue (e.g. Block the sender). In
msgrcv call, msg-struct-ptr is the address of the structure to receive the message, maxcount is
maximum length of message, type indicates the type of message to be received. When a message
is sent to a message queue on which many processes are waiting, the operating system wakes all
processes. When type parameter in msgrcv is positive, the operating system returns the first
message with a matching type and if it is negative, the operating system returns the lowered
number message with the type value less than the absolute value specified in the call. An echo
server is usually an application which is used to test if the connection between a client and a
server is successful. It consists of a server which sends back whatever text the client sends. The
program shows communication between 2 processes using the IPC mechanism: message queues
Algorithm:
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include<unistd.h>
int main()
{
int pid, msgid;
char str[30],buf[30];
msgid = msgget((key_t)101,IPC_CREAT|0600);
pid = fork();
if(pid==0)
{
strcpy(str,"Message Queue demo");
msgsnd(msgid,str,sizeof(str),0);
}
else if(pid>0)
{
msgrcv(msgid,buf,sizeof(buf),0,0);
printf("message recieved: %s \n",buf);
}
else
{
perror("Error is creating msg queue");
}
}
Output:
IPC Message Queue 2:
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include<unistd.h>
int main()
{
int pid, msgid;
char str[30],buf1[30],buf2[30];
msgid = msgget((key_t)134,IPC_CREAT|0600);
pid = fork();
if(pid==0)
{
strcpy(str,"Message From child to parent");
msgsnd(msgid,str,sizeof(str),0);
msgrcv(msgid,buf1,sizeof(buf1),0,0);
printf("message recieved: %s \n",buf1);
}
else if(pid>0)
{
strcpy(str,"Message from parent to child");
msgrcv(msgid,buf2,sizeof(buf2),0,0);
msgsnd(msgid,str,sizeof(str),0);
printf("message recieved: %s \n",buf2);
}
else
{
perror("Error is creating msg queue");
}
}
Output:
Operating Systems Lab
Program: 5(D)
AIM: Program to demonstrate usage of Shared Memory
Problem Definition: To demonstrate basic operations with shared memory
Problem Description: Shared Memory is an efficient means of passing data between
programs. One program will create a memory portion which other processes (if permitted) can
access. A process creates a shared memory segment using shmget. Once created, a shared
segment can be attached to a process addressspace using shmat(). It can be detached using
shmdt(). Once attached, the process can read or write to the segment, as allowed by the
permission requested in the attach operation. A shared memory segment is described by a control
structure with a unique ID that point to an area of physical memory. The identifier of the segment
is called the shmid. The structure definition for the shared memory segment control structures and
prototype can be found in <sys/shm.h>
shmget () - allocates a System V shared memory segment
System Calls used: shmget (),shmat(), shmdt()
Syntax:
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);.
The argument key is the value of the IPC key to use. The size argument specifies the minimum size of the shared
memory region required. The flag option must contain the permission bits if shared memory is being created.
Additional flags that may be used include IPC_CREAT and IPC_EXCL, when shared memory is being created.
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
Return: On success shmat() returns the address of the attached shared memory segment; on error (void *) -1 is
returned.
On success shmdt() returns 0; on error -1 is returned, and errno is set to indicate the cause of the error.
Algorithm:
1: The parent process creates the shared memory. A child process is created.
2: The child process attaches to the shared memory and writes a message into it
3: The parent process reads the message from shared memory and prints it
Shared Memory 1:
#include<stdio.h>
#include<string.h>
#include<sys/shm.h>
#include<unistd.h>
#include<sys/ipc.h>
int main()
{
int pid,shmid;
char *p1;
shmid= shmget((key_t)150,100,IPC_CREAT|0600);
p1=(char *)shmat(shmid,0,0);
pid=fork();
if(pid==0)
{
strcpy(p1,"demo of shared memory");
}
else if(pid>0)
{
printf("shared memory is %s \n",p1);
}
}
Output:
Shared Memory 2:
#include<stdio.h>
#include<string.h>
#include<sys/shm.h>
#include<unistd.h>
#include<sys/ipc.h>
int main()
{
int pid,shmid;
char *p1,*p2;
shmid= shmget((key_t)150,100,IPC_CREAT|0600);
p1=(char *)shmat(shmid,0,0);
p2=(char *)shmat(shmid,0,0);
pid=fork();
if(pid==0)
{
strcpy(p1,"demo of shared memory");
printf("shared memory from parent: %s",p2);
}
else if(pid>0)
{
printf("shared memory is %s \n",p1);
strcpy(p2,"demo of shared memory");
}
}
Output:
Operating Systems Lab
Program: 6(A)
AIM: Program to simulate solution for producer consumer problem
Problem Definition: To write a program to simulate a solution for producer consumer
problem
Problem Description: The program implements solution for the classical synchronization
problem- Producer consumer. Producer-Consumer problem is a classical example of a multi
process synchronization problem. The problem describes two processes, the producer and the
consumer, who share a common, fixed-size buffer. The producer's job is to generate a piece of
data, put it into the buffer and start again. At the same time the consumer is consuming the data
(i.e. removing it from the buffer) one piece at a time. A producer process produces information
that is consumed by a consumer process. A producer can produce one item while the consumer is
consuming another item. The producer and consumer must be synchronized, so that the
consumer does not try to consume an item that has not yet been produced. Two types of buffers
can be used. The problem is to make sure that the producer won’t try to add data into the buffer if
it’s full and that the consumer won’t try to remove data from an empty buffer.
The solution for the producer is to go to sleep if the buffer is full. The next time the
consumer remove an item from the buffer, it wakeup the producer who start to fill the buffer
again. In the same way the consumer goes to sleep if it finds the buffer to be empty. The next
time the producer puts data into the buffer, it wakeup the sleeping consumer. The solution can be
reached by means of IPC, typically using semaphores.
Semaphores are synchronization primitives. They are not used for exchanging large
amount of data, but are intended to let multiple processes synchronize their operation. A
semaphore is an integer variable with two atomic operation wait and signal.
Semaphores solve the problem of lost wakeup calls. In the solution below we use two
semaphores, full count and empty count, to solve the problem. Full count is incremented and
empty count is decremented when a new item has been put into the buffer. If the producer’s tries
to decrement empty count while its value is zero. The producer is put to sleep. The next time an
item is consumed; empty count is increment and the producer wake up. The consumer works
analogously.
Algorithm:
Producer Consumer:
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/sem.h>
int mutex=1,full=0,empty=3,x=0;
main()
{
int n;
void producer();
void consumer();
int wait();
int signal();
printf("\[Link]\[Link]\[Link]\n");
while(1)
{
printf("\nEnter your choice:");
scanf("%d",&n);
switch(n)
{
case 1:if((mutex==1) && (empty!=0))
producer();
else
printf("\nBuffer is full");
break;
case 2:if((mutex==1) && (full!=0))
consumer();
else
printf("\nBuffer is empty");
break;
case 3:exit(1);
}
}
}
int wait(int s)
{
return (--s);
}
int signal(int s)
{
return (++s);
}
void producer()
{
mutex=wait(mutex);
full=signal(full);
empty=wait(empty);
x++;
printf("\nProducer produced the item %d\n",x);
mutex=signal(mutex);
}
void consumer()
{
mutex=wait(mutex);
full=wait(full);
empty=signal(empty);
printf("\nConsumer consumed the item %d\n",x);
x--;
mutex=signal(mutex);
}
Output:
Operating Systems Lab
Program: 6(B)
AIM: Program to demonstrate solution for readers writers problem using
semaphores
Problem Definition: To write a program to implement a solution for Readers-Writers
problem using semaphores
Problem Description: The program implements solution for the classical synchronization
problem- Reader-Writer using Semaphore. Semaphores can be used to restrict access to the
database under certain conditions. In this example, semaphores are used to prevent any writing
processes from changing information in the database while other processes are reading from the
database. A database is to be shared among several concurrent processes. Some of these
processes may want only to read the database, whereas others may want to update (that is, to
read and write) the database. We distinguish between these two types of processes by referring to
the former as readers and to the latter as writers. Obviously, if two readers access the shared data
simultaneously, no adverse affects will result. However, if a writer and some other thread (either
a reader or a writer) access the database simultaneously, chaos may ensue. To ensure that these
difficulties do not arise, we require that the writers have exclusive access to the shared database.
This synchronization problem is referred to as the readers-writers problem.
In the solution to the first readers-writers problem, the reader processes share the
following data structures:
semaphore mutex, wrt;
int readcount;
Mutex –locks that provide mutual exclusion (i.e. if process Pi is executing in its critical section,
then no other processes can be executing in their critical section). The semaphores mutex and wrt
are initialized to 1; readcount is initialized to 0. The semaphore wrt is common to both reader
and writer processes. The mutex semaphore is used to ensure mutual exclusion when the variable
readcount is updated. The readcount variable keeps track of how many processes are currently
reading the object. The semaphore wrt functions as a mutual exclusion semaphore for the writers.
It is also used by the first or last reader that enters or exits the critical section. It is not used by
readers who enter or exit while other readers are in their critical sections.
Note that, if a writer is in the critical section and n readers are waiting, then one reader is queued
on wrt, and n-1 readers are queued on mutex. Also observe that, when a writer executes signal
(wrt), we may resume the execution of either the waiting readers on a signal waiting writing. The
selection is made by the scheduler.
Algorithm:
Reader writer:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#include<semaphore.h>
sem_t rwmutex,mutex;
int rc=0,data=0;
int main()
{
pthread_t wtid[5],rtid[5];
int i;
sem_init(&mutex,0,1);
sem_init(&rwmutex,0,1);
for(i=0;i<5;i++)
{
pthread_create(&wtid[i],NULL,writer,(void *)i);
pthread_create(&rtid[i],NULL,reader,(void *)i);
}
for(i=0;i<5;i++)
{
pthread_join(wtid[i],NULL);
pthread_join(rtid[i],NULL);
}
}
Output:
Operating Systems Lab
Program: 6(C)
AIM: Program to demonstrate solution for dining philosopher problem using
semaphores
Problem Definition: To write a program to implement a solution for dining philosopher
problem using semaphores and shared memory
Problem Description: The dining-philosophers problem is considered a classic
synchronization problem because it is an example of a large class of concurrency-control
problems. It is a simple representation of the need to allocate several resources among several
processes in a deadlock-free and starvation-free manner. Consider five philosophers who spend
their lives thinking and eating. The philosophers share a circular table surrounded by five chairs,
each belonging to one philosopher. In the center of the table is a bowl of rice, and the table is laid
with five single chopsticks. When a philosopher thinks, she does not interact with her colleagues.
From time to time, a philosopher gets hungry and tries to pick up the two chopsticks that are
closest to her (the chopsticks that are between her and her left and right neighbors). A
philosopher may pick up only one chopstick at a time. Obviously, she cannot pick up a chopstick
that is already in the hand of a neighbor. When a hungry philosopher has both her chopsticks at
the same time, she eats without releasing her chopsticks. When she is finished eating, she puts
down both of her chopsticks and starts thinking again. The dining-philosophers problem may
lead to a deadlock situation and hence some rules have to be framed to avoid the occurrence of
deadlock.
One simple solution is to represent each chopstick with a semaphore. A philosopher tries
to grab a chopstick by executing a wait () operation on that semaphore; she releases her
chopsticks by executing the signal() operation on the appropriate semaphores. Thus, the shared
data are semaphore chopstick[5]; where all the elements of chopstick are initialized to 1. Use an
asymmetric solution; that is, an odd philosopher picks up first her left chopstick and then her
right chopstick, whereas an even philosopher picks up her right chopstick and then her left
chopstick
Although this solution guarantees that no two neighbors are eating simultaneously, it
nevertheless must be rejected because it could create a deadlock. Suppose that all five
philosophers become hungry simultaneously and each grabs her left chopstick. All the elements
of the chopstick will now be equal to 0. When each philosopher tries to grab her right chopstick
she will be delayed forever.
Alternate solution is to let a philosopher take chopsticks only if both of them (i.e on her left and
right) are available and her neighbors are not in eating state. We need to have another state called
HUNGRY to code the deadlock-free solution.
state[5]={THINKING,HUNGRY,EATING}
state[i]=EATING iff (state[(i+4)%5] !=EATING) && (state[(i+1)%5] != EATING)
Algorithm:
1: Define number of philosophers as N=5 i.e{0,1,2,3,4}, and
state[N]={THINKING, HUNGRY,EATING}
2: Philosophers neighbors are defined as LEFT (phnum+N-1) % N and RIGHT (phnum+1) % N
3: Declare mutex and s[N] semaphore variables and initialize mutex=1 and s[i]=0 where ‘i’ is the
philosopher number.
4: Create philosopher processes by using pthread. And call philosopher() upon start of
thread.
5: From the philosopher function call take_fork(*i).
6: Wait for mutex within take_fork() and then stae that philosopher is hungry and eat if
neighbors are not eating, this can be done by calling test(phnum).
7. Within test(), make, state[i]=EATING if and only if (state[(i+4)%5] !=EATING) &&
(state[(i+1)%5] != EATING). Then signal the state s[phnum] by calling sem_post which is used
to wakeup hungry philosophers during put fork.
8. After eating call sem_post(mutex). If unable to eat wait is to be signaled by using
sem_wait()
9. After eating call put_fork() to put down the chopsticks.
10. Within put_fork(), wait for mutex by using sem_wait() and then change the state as
THINKING and then test whether the neighbors of this philosopher who are HUNGRY can wake
up and go into EATING state. The program continues and pthread_join continues to wait forever.
Program:
DINING PHILOSOPHER:
#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>
#define N 5
#define THINKING 2
#define HUNGRY 1
#define EATING 0
#define LEFT (phnum+N-1)%N
#define RIGHT (phnum)%N
int state[N];
int phil[N]={0,1,2,3,4};
sem_t mutex;
sem_t S[N];
void test(int phnum){
if(state[phnum]==HUNGRY && state[LEFT]!=EATING &&
state[RIGHT]!=EATING){
state[phnum]=EATING;
sleep(2);
printf("Philosopher %d takes %d fork and %d
fork\n",phnum,LEFT,RIGHT);
printf("%d is eating\n",phnum);
sem_post(&S[phnum]);
} }
void takeFork(int phnum){
sem_wait(&mutex);
state[phnum]=HUNGRY;
printf("%d is hungry\n",phnum);
test(phnum);
sem_post(&mutex);
sem_wait(&S[phnum]);
sleep(1);
}
void putFork(int phnum){
sem_wait(&mutex);
state[phnum]=THINKING;
printf("philosopher %d putting fork %d and %d\n",phnum,LEFT,RIGHT);
printf("philosopher %d is thinking\n",phnum);
test(LEFT);
test(RIGHT);
sem_post(&mutex);
}
void *philosopher(void *num){
while(1){
int *i=num;
sleep(1);
takeFork(*i);
sleep(1);
putFork(*i);
} }
int main(){
int i;
pthread_t tid[N];
sem_init(&mutex,0,1);
for(i=0;i<N;i++){
sem_init(&S[i],0,0);
}
for(i=0;i<N;i++){
pthread_create(&tid[i],NULL,philosopher,&phil[i]);
printf("philosopher %d is thinking\n",phil[i]);
}
for(i=0;i<N;i++){
pthread_join(tid[i],NULL); } }
Output:
Operating Systems Lab
Program: 7
AIM: Program to simulate Bankers Algorithm for Deadlock avoidance
Bankers Algorithm:
#include<stdio.h>
#include<stdlib.h>
int main(){
int
max[10][10],need[10][10],allocation[10][10],available[10],finished[10
],safeseq[10];
int pr_cnt,res_cnt,i,j,count=0,process;
system("clear");
printf("\nEnter the system state information\n");
printf("Enter the no of processes:\n");
scanf("%d",&pr_cnt);
for(i=0;i<pr_cnt;i++){
finished[i]=0;
}
printf("Enter the no of resources:\n");
scanf("%d",&res_cnt);
printf("Enter the max matrix for all the processes:\n");
for(i=0;i<pr_cnt;i++){
printf("Enter max info for process[%d]:",i+1);
for(j=0;j<res_cnt;j++){
scanf("%d",&max[i][j]);
}
}
for(i=0;i<pr_cnt;i++){
printf("Enter allocation info for process[%d]\n",i+1);
for(j=0;j<res_cnt;j++){
scanf("%d",&allocation[i][j]);
}
}
printf("Enter the available resources in the system:\n");
for(i=0;i<res_cnt;i++){
printf("\navailable[%d]=",i);
scanf("%d",&available[i]);
}
for(i=0;i<pr_cnt;i++){
for(j=0;j<res_cnt;j++){
need[i][j]=max[i][j]-allocation[i][j];
}
}
do{
printf("\nAvailable resources are: \t");
for(j=0;j<res_cnt;j++)
printf("%d",available[j]);
printf("\nmax matrix:\tallocation matrix:\n");
for(i=0;i<pr_cnt;i++){
24
for(j=0;j<res_cnt;j++){
printf("%d",max[i][j]);
}
printf("\t");
for(j=0;j<res_cnt;j++){
printf("%d",allocation[i][j]);
}
printf("\n");
}
process=-1;
for(i=0;i<pr_cnt;i++){
if(finished[i]==0){
process=i;
for(j=0;j<res_cnt;j++){
if(available[j]<need[i][j]){
process=-1;
break;
}}}
if(process!=-1)
break;
}
if(process!=-1){
safeseq[count]=process+1;
count++;
for(j=0;j<res_cnt;j++){
available[j]+=allocation[process][j];
allocation[process][j]=0;
max[process][j]=0;
finished[process]=1;
}
}
}while(count!=pr_cnt && process!=-1);
if(count==pr_cnt){
printf("\nthe system is in a safe state\n");
printf("\nSafe sequence:<");
for(i=0;i<pr_cnt;i++)
printf("%d",safeseq[i]);
printf(">\n");
}
else{
printf("\nthe system is in unsafe state!!\n");
}
}
Output:
Operating Systems Lab
Program: 8(A)
AIM: Program to simulate First In First Out Page Replacement Algorithm
Algorithm:
#include<stdio.h>
main()
{
int i,j,n,a[50],frame[10],no,k,avail,count=0;
for(i=0;i<no;i++)
frame[i]=-1;
j=0;
printf("\nref_str\tpageframe\n");
for(i=1;i<=n;i++)
{
printf("%d\t",a[i]);
avail=0;
for(k=0;k<no;k++)
{
if(frame[k]==a[i])
avail=1;
}
if(avail==0)
{
frame[j]=a[i];
27
j=(j+1)%no;
count++;
for(k=0;k<no;k++)
printf("%d\t",frame[k]);
}
printf("\n");
}
printf("[Link] page faults = %d\n",count);
}
Output:
Operating Systems Lab
Program: 8(B)
AIM: Program to simulate Least Recently Used Page Replacement Algorithm
Algorithm:
#include<stdio.h>
main()
{
int i,j,k,min,rs[25],m[10],count[10],flag[25],n,f,pf=0,next=1;
{
if(i<f){
m[i]=rs[i];
count[i]=next;
next++;
}
else{
min=0;
for(j=1;j<f;j++)
if(count[min]>count[j])
min=j;
m[min]=rs[i];
count[min]=next;
next++;
}
pf++;}
for(j=0;j<f;j++)
printf("%d\t",m[j]);
if(flag[i]==0)
printf("pf = %d",pf);
printf("\n");}
printf("[Link] page faults = %d\n",pf);
}
Output:
Operating Systems Lab
Program: 9(A)
AIM: Program to simulate implementation of FCFS disk scheduling
algorithm
Problem Definition: To write a program to simulate implementation of FCFS disk
scheduling algorithm
Problem Description: 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.
FCFS (First-Come, First-Served) Disk Scheduling Algorithm is a simple and easy-to-implement
algorithm used in operating systems to manage input/output (I/O) requests from processes to
access disk blocks. In this algorithm, the operating system processes the I/O requests in the order
in which they arrive in the queue, without any reordering or prioritization.
When a process generates an I/O request, it is added to the end of the queue, and the operating
system services the requests in the same order. The requests are serviced one by one until the
entire queue is empty. This algorithm has the advantage of being fair, predictable, and requiring
low overhead. However, it also has limitations, such as long waiting times for requests that arrive
later and potential starvation of requests that are stuck behind long-running requests.
Algorithm:
1. Let Request array represents an array storing indexes of tracks that have been requested in
order of their time of arrival. ‘head’ is the position of disk head.
2. Take the tracks in order of their arrival and calculate the absolute distance of the track from
the head.
4. Currently serviced track position now becomes the new head position.
5. Go to step 2 until all tracks in request array have not been serviced.
7. Close .
Program:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int req[10],n,hdpos,tseek=0,i;
float avg;
printf("Enter the number of requests:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("\nEnter the disk read request number %d:\t",i);
scanf("%d",&req[i]);
}
printf("\nEnter the head position:\t");
scanf("%d",&hdpos);
Output:
Operating Systems Lab
Program: 9(B)
AIM: Program to simulate implementation of SSTF disk scheduling algorithm
Algorithm:
1. Let Request array represents an array storing indexes of tracks that have been requested.
‘head’ is the position of disk head.
2. Find the positive distance of all tracks in the request array from head.
3. Find a track from requested array which has not been accessed/serviced yet and has minimum
distance from head.
5. Currently serviced track position now becomes the new head position.
6. Go to step 2 until all tracks in request array have not been serviced.
8. Close.
Program:
#include<stdio.h>
#include<math.h>
main()
{
int diskreq[20],temp[20],n,diskhdpos;
int i,totseek=0,min,diff,index,cnt, tpos;
float avgdiskmove;
printf ("Enter the number of disk read requests\n");
scanf("%d",&n);
while(cnt < n){min = 999999; //find the next disk causes least disk
head movement
for(i=0;i<n;i++)
if (temp[i] != -1)
{ diff = abs(diskreq[i] - tpos);
if (min > diff){
min = diff;
index = i; //point to the next disk read request to service
}
}
totseek+= min;
temp[index] = -1; // temp array is used to keep track of
completed requests.
printf("Disk head movement from %d to %d is [%d]
\n",tpos,diskreq[index],min);
cnt++;
tpos = diskreq[index];
if (cnt == n)
break;
}
avgdiskmove = (float ) totseek/n;
printf("Total seek time to process the above [%d] disk read requests
is %d\n",n,totseek);