0% found this document useful (0 votes)
17 views48 pages

Os Lab Record

tgfgsdfg

Uploaded by

navadeepsatheesh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views48 pages

Os Lab Record

tgfgsdfg

Uploaded by

navadeepsatheesh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 48

COLLEGE OF ENGINEERING TRIVANDRUM

THIRUVANANTHAPURAM-695016

DEPARTMENT OF
COMPUTER SCIENCE AND ENGINEERING

Fourth Semester
CSL204 : OPERATING SYSTEMS LAB

Name: NAVADEEP SATHEESH

KTU ID : TVE22CS100

APJ ABDUL KALAM TECHNOLOGICAL UNIVERSITY 2023 – 2024


COLLEGE OF ENGINEERING TRIVANDRUM
THIRUVANANTHAPURAM-695016

DEPARTMENT OF
COMPUTER SCIENCE AND ENGINEERING

Fourth Semester
CSL204 : OPERATING SYSTEMS LAB

Certified that this a bonafide record of the work done by NAVADEEP SATHEESH
(TVE22CS100) of S4 CSE (Batch-2) class in the Operating Systems Lab during the year
2023-2024.
Faculty in Charge

External Examiner
INDEX

Serial Date of Page


Experiment
No Performance No
1 Basic Linux Commands 15-03-2024 1

2 Shell Progamming-1 15-03-2024 5

3 Shell Progamming-2

4 System Calls – 1 7-03-2024 13

5 System Calls – 2 7-03-2024 19

6 CPU Scheduling Algorithms 22-04-2024 28


Interprocess Communication using Shared
7 22-04-2024 39
Memory
8 Producer Consumer Problem

9 Dining Philosophors Problem

10 Memory Allocation Methods

11 Page Replacement Algorithms

12 Banker’s Algorithm for Deadlock Avoidance

13 Deadlock Detection Algorithm

14 Disk Scheduling Algorithms

1
Ex.No. 1 BASIC LINUX COMMANDS
Date : 03-02-24

Aim :- Study the purpose and usage of basic Linux Commands.


1) clear
Purpose : To clear the screen
Usage : clear
2) date
Purpose : To display the system date and time. Also be used for setting date and
time
usage : date

3. Cal

Purpose: To print the days of the month in calendar format


Usage: cal

4. pwd
Purpose: To display the path of the current directory
Usage: pwd

5. ls
Purpose: To list the contents of the current directory
Usage: ls

1
2
6. ls -l
Purpose : To list the contents of the current directory in long listing format
Usage : ls -l

7. ls -a

Purpose: To list the contents of the current directory, including all hidden files
Usage: ls -a

8. mkdir
Purpose: To create a new directory
Usage: mkdir

9. cd
Purpose: Change directory to path specifed
Usage: cd <path>

3
10. rmdir
Purpose: To delete empty directories
Usage: rmdir <dir_name>

11. touch
Purpose: To change file timestamps (create file if file does not exist)
Usage: touch

4
Exp no:-2 SHELL PROGRAMMING 1
DATE:22-02-2024

Aim:- Write shell scripts for the following questions:


(a) Find the sum of digits and reverse of a counting number, using command line
argument.
Shell script:_

temp=$1;
sum_digit=0
rev=0
while [ $temp -gt 0 ]
do
ld=$((temp%10 ))
sum_digit=$((sum_digit+ld))
rev=$((rev*10 +ld))
temp=$((temp/10))
done
echo "reverse is "
echo $rev
echo "sum is "
echo $sum_digit

Sample Output:-

Result:- Program is executed successfully , output is obtained and verified.

5
(B) display all Armstrong number between two given numbers

Shell script:_
# aim- to display armstrong numbers between two numbers

#Function to calculate the number of digits in a number


count_digits()
{
local num = $1
local count = 0
while[$num - gt 0];
do
num = $((num / 10))
count = $((count + 1))
done
echo "$count"
}
#Function to check if a number is an Armstrong number
is_armstrong()
{
local num = $1
local num_digits = $(count_digits $num)
local sum_of_powers = 0 local temp_num = $num
while[$temp_num - gt 0];
do
local digit = $((temp_num % 10))
sum_of_powers = $((sum_of_powers + digit * *num_digits))
temp_num = $((temp_num / 10))
done
if[$sum_of_powers - eq $num - a $num - gt 9]; then
return 0
}
#Function to find Armstrong numbers between two given numbers
find_armstrong_numbers()
{
local start = $1
local end = $2
echo "Armstrong numbers between $start and $end are:"
if[$1 - le 1]; then
echo "1"
fi

6
for ((i = start; i <= end; i++));
do
if is_armstrong $i;then
echo "$i" fi
done
}
#Main script
read - p "Enter the starting number: "
start_num read - p "Enter the ending number: "
end_num find_armstrong_numbers $start_num $end_num

Sample Output:-

Result:- Program is executed successfully , output is obtained and verified.

( C ) Write a menu driven program for converting a positive decimal number to


binary, octal or hexadecimal according to the choice of the user.

Shell script:_
.

#function to convert decimal to binary


binary()
{
local dec=$1
bin=()
i=0
while [ $dec -gt 0 ]
do
temp=$((dec%2))

7
bin[i]=$temp
dec=$((dec/2))
i=$((i+1))
done
echo -n "binary is :"
while [ $i -ge 0 ]
do
echo -n "${bin[i]}"
i=$((i-1))
done
echo ""
}

#function to convert decimal to hexadecimal


hexadecimal()
{
local dec=$1
i=0
hex=()

while [ $dec -gt 0 ]


do
temp=$((dec%16))
case $temp in
10)
hex[i]="A"
;;
11)
hex[i]="B"
;;
12)
hex[i]="C"
;;
13)
hex[i]="D"
;;
14)
hex[i]="E"
;;
15)
hex[i]="F"
;;
*)
hex[i]=$temp

8
;;
esac
i=$((i+1))
dec=$((dec/16))
done
echo -n "hexa decimal is :"
while [ $i -ge 0 ]
do
echo -n "${hex[i]}"
i=$((i-1))
done
echo ""
}

#function to convert decimal to octal


octal()
{
local dec=$1
oct=()
i=0
while [ $dec -gt 0 ]
do
temp=$((dec%7))
oct[i]=$temp
dec=$((dec/7))
i=$((i+1))
done
echo -n "octal is :"
while [ $i -ge 0 ]
do
echo -n "${oct[i]}"
i=$((i-1))
done
echo ""
}

#main
read -p "enter the decimal " dec
binary $dec
hexadecimal $dec
octal $dec

9
Sample Output:-

Result:- Program is executed successfully , output is obtained and verified.

( d ) Input a date in the form dd/mm/yyyy and check whether it is a valid date in
the range 01/01/1951 to 31/12/2025.

Shell script:

echo "Enter a date: DD/MM/YYYY" #to read the date


read date
day=${date:0:2}
day=${day#0}
month=${date:3:2}
month=${month#0}
year=${date:6:4}
leap=false

if [[ $year -ge 1951 && $year -le 2025 ]]; then


if [[ year%4 -eq 0 && year%100 -ne 0 || year%400 -eq 0 ]]; then
leap=1
else
leap=0
fi
if [[ month -ge 1 && month -le 12 ]]; then
if [[ month -eq 1 || month -eq 3 || month -eq 5 || month -eq 7 || month -eq 8 ||
month -eq 10 || month -eq 12 ]]; then
if [[ day -ge 1 && day -le 31 ]]; then
echo "valid date"
else
echo "invalid date - day"
fi

10
elif [[ month -eq 4 || month -eq 6 || month -eq 9 || month -eq 11 ]]; then
if [[ day -ge 1 && day -le 30 ]]; then
echo "valid date"
else
echo "invalid date-day"
fi
elif [[ month -eq 2 ]]; then
If [[ leap ]]; then
echo $leap
if [[ day -ge 1 && day -le 29 ]]; then
echo "Valid date"
else
echo "invalid date - day"
fi
else
if [[ day -ge 1 && day -le 28 ]]; then
echo "Valid date"
else
echo "invalid date - day"
fi
fi
fi
else
echo "Invalid date - month"
fi
else
echo "invalid date - year "
fi
Sample output:

Result: Program is executed successfully , output is obtained and verified.

11
12
Expt. No. 4 SYSTEM CALLS 1
Date: 07-03-2024

Aim: Write programs for illustrating the working of the the following sys- tem calls
in Linux:
fork(), getpid(), getppid(), execv(), wait(), exit()
System Calls:

1. fork()
Description:-
fork() is used to create new process. Creates a copy of the parent process.
fork() returns the PID of the child process to parent and 0 to the child process.
It retruns -1 if not able to create new process. After creating new process parent
and child processes starts execution from the statement immediately followed by
fork () call.
Program code : -

/*
Exp no 4
Program to find the return value of fork() to parent and child
*/
#include <stdio.h>
#include <unistd.h>
int main ()
{
pid_t p=fork() ;
printf("Hello \n") ;
printf ("Value returned to %s by fork() = %d,processID = %d\n",(p == 0?"CHILD":"
PARENT" ),p ,getpid());
return 0 ;
}

Sample output:

13
2. execv()
Description:-
The execv() function replaces the current process image with a new process
image specifed by path . The new image is constructed from a regular,
executable file called the new process image file. No return is made because
the calling process image is replaced by the new process image.
Syntax: int execv(const char * path, char * const argv[]);

Program code : -
/*
Exp no -4
Name : Navadeep Satheesh
Roll no : 41
Program to demonstrate the function of exec() system call

*/
#include <stdio.h>
#include <unistd.h>

int main() {
char *args[] = {"./executable", "Testing", "Hullo", NULL};

printf("Process ID of main program: %d\n", getpid());

// Call the child program


execv(args[0], args);

// This line won't be executed after execv call


printf("End of program 1.\n");

return 0;
}

Child program:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {


printf("In the program 2.\n");
printf("PID of program 2: %d\n", getpid());
printf("String passed: %s\n", argv[1]);
printf("Argc = %d\n", argc);
printf("End of program 2.\n");

return 0;
}

14
Sample output:

3. Wait()

1. Description:-
The wait() system call suspends execution of the calling thread untilone of its
children terminates. A call to wait() blocks the calling processuntil one of its child
processes exits or a signal is received. After child process terminates, parent
continues its execution after wait system call instruction.

Program code : -

/*
Exp no -4
Program to demonstrate the function of exec() system call
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int main() {
if (fork() == 0) {
printf("inside child\n");
} else {
printf("inside parent\n");
// wait(NULL);
printf("child has terminated\n");
}
printf("done\n");
return 0;
}

15
Sample output:-

4. getpid(), getppid()

1. Description:-
getppid() returns the process ID of the parent of the calling process.If the calling
process was created by the fork() function and the parent process still exists at the
time of the getppid function call, this function returns the process ID of the parent
process. Otherwise, this function returns a value of 1 which is the process id for
init process.
getpid() returns the process ID of the calling process.

Program code:
/*
Exp no -4
Name : Navadeep Satheesh
Roll no : 41
Program to demonstrate the function of getpid() and getppid() system call
*/
#include <stdio.h>
#include <unistd.h>

int main()
{
int pid, ppid;
printf("Program to find process ID:\n");
pid = getpid();
printf("Process ID of running process: %d\n", pid);
ppid = getppid();
printf("Process ID of the parent process: %d\n", ppid);
return 0;
}
Sample output:-

16
17
5. exit()
Description:-
The C exit() function is a standard library function used to terminate the calling
process. When exit() is called, any open le descriptors belonging to the process
are closed and any children of the process are inherited by process 1, init, and the
process parent is sent a SIGCHLD signal.
An exit status of 0 means that the program has executed successfully, while a status
of 1 means that an error was encountered.

Program code:
/*
Exp no -4
Program to demonstrate the function of exit()system call
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void function();
int main() {
printf("Current process ID: %d\n", getpid());
function();
printf("Will not be executed\n");
return 0;
}

void function() {
printf("Inside function().\n");
printf("Current process ID: %d\n", getpid());
exit(5);
printf("This is written after exit() in the function\n");
}

Sample output:-

18
Exp no : 5 I/O SYSTEM CALLS
DATE: 15-03-2024

Aim: Write programs for illustrating the working of the the following system calls in
Linux :
opendir(), readdir(), open(), read(), stat(), write(), close()
System Calls

1. opendir(), readdir()
Description:-
The opendir() function opens a directory stream corresponding to the directory
name, and returns a pointer to the directory stream. The stream is positioned at the
first entry in the directory The readdir() function returns a pointer to a dirent
structure representing the next directory entry in the directory stream pointed to by
dirp. It returns NULL on reaching the end of the directory stream or if an error
occurred.

Program code:
/*
Exp no-5
Date:15-03-2024
Roll no : 42
Write a c program to display the content of a directory given as a command lie
argument
*/
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>

void main(int argc, char *argv[]) {


// Name of directory passed as command line argument
char *dname = argv[1];
DIR *dr;
struct dirent *de;

if (argc == 2) {
dr = opendir(dname);
if (dr == NULL) {
printf("Could not open directory.\n");

19
} else {
printf("Contents of directory:\n");
printf("========================\n");
while ((de = readdir(dr)) != NULL) {
printf("%s\n", de->d_name);
}
closedir(dr); // Close the directory after reading its contents
}
} else {
printf("Usage: ./dir <dirname>\n");
}
}

Sample output:

2 write()
Description:-
The write() function will write the specifed number of bytes (passed to it as an
argument) from a buffer (a pointer to which is passed as an argument) into a file
specifed by a file descriptor.
It returns a value of 0 if the number of bytes is 0, -1 if there is an error, and no value
in all other cases.
Syntax: ssize_t write(int fildes, const void *buf, size_t nbyte);

20
Program code:
/*
Exp no-5
Date:15-03-2024
Write a c program writing and reading from stdout
*/
#include <unistd.h>
#include <string.h>
int main() {
char name[60];
char *str = "Name: ";
char *str1 = " Entered name: ";
int n;
// Write contents of str to stdout
write(1, str, strlen(str));
// Return the number of bytes read from stdin
n = read(0, name, 60);
write(1, str1, strlen(str1)); // Write to stdout
write(1, name, n);
return 0;
}

Sample output:

3. open(), read(), stat(), close()


Description:-
The open() system call attempts to read up to count bytes from file descriptor fd into
the buffer starting at buf. Syntax: int open(const char *pathname, int flags, mode_t
mode); The read() system call opens the file specifed by pathname. If the specifed file
does not exist, it may optionally (if O_CREAT is specifed in pags) be created by
open(). The return value of open() is a file descriptor.
Syntax: size_t read(int fd, void *buf, size_t count);

The stat() system call return information about a file, in the buffer pointed to by
statbuf.
Syntax: int fstat(int fd, struct stat *statbuf);

21
The close() closes a file descriptor, so that it no longer refers to any file and may be
reused.
Syntax: int close(int fd);

22
Program code:

/*
Exp no-5
Navadeep
Satheesh
Date:15-03-2024
Roll no : 41
Program to convert lowercase of text file to upper case and store it in another file
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int main() {
struct stat sb;
char fname[30], ch, c;
int fd1, fd2, n;

printf("File name: ");


scanf("%s", fname);

fd1 = open(fname, O_RDONLY);

if (fd1 > 0) {
fd2 = open("file2.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
while ((n = read(fd1, &ch, 1)) > 0)
{
c = ch;
ch = (c >= 'a' && c <= 'z') ? c - 32 : c;
write(fd2, &ch, 1);
}
close(fd2);
}else {
printf("File %s not found.\n", fname);
}
stat("file2.txt", &sb);
printf("Stats of file2.txt:\n");
printf("Inode number: %lu\n", sb.st_ino);
printf("Number of hard links: %lu\n", sb.st_nlink);

close(fd1);
return 0;

23
}

Sample output:

24
Ex.No. 6 CPU SCHEDULING ALGORITHMS
Date:-22-03-2024

Aim :- Write a menu driven program for implementing the following CPU scheduling
algorithms.
(a) FCFS (b) Round Robin (c) SJF (d) Priority
For all the programs, arrival time for the processes should be considered. For each
case find the turnaround time, waiting time and display a Gantt chart. Also find the
average waiting time and average turn around time. Output should be verified with
atleast 5 processes.

A )First Come First Serve (FCFS) Scheduling

Description : FCFS is one of the simplest CPU scheduling algorithms. It schedules processes
based on their arrival time, executing the earliest arriving process first. While fair and easy to
implement, FCFS may lead to the convoy effect, where long processes delay shorter ones,
causing inefficient resource utilization. It's suitable for simple systems with predictable
process behavior but may not be optimal for systems with varied process execution times.

B ) Round robin

Description : a preemptive CPU scheduling algorithm widely used in multitasking systems,


allocates CPU time to processes in fixed-length time slices, known as time quanta. Upon
expiration of a process's time quantum, it's preempted, and the CPU is assigned to the next
process in the ready queue. RR ensures fairness by providing each process an equal
opportunity to execute, preventing any single process from monopolizing the CPU. While
offering good responsiveness, particularly for interactive tasks, RR may incur overhead due
to frequent context switching, impacting system performance if the time quantum is too
short. Despite this, RR finds extensive use in time-sharing and interactive systems, where fair
CPU allocation and responsiveness are paramount.

C ) Short Job First ( sfj )

Description : sfj is a non-preemptive scheduling algorithm used to minimize the average


waiting time of processes. In SJF, the process with the shortest burst time is selected for
execution first. This ensures that shorter jobs are completed before longer ones, reducing
waiting times. While SJF offers optimal average waiting times for a given set of processes, it
requires knowledge of each process's burst time in advance, which may not always be
feasible in practical scenarios. Additionally, SJF may suffer from starvation for longer
processes if short processes frequently arrive.

25
D) Priority

Descripton : Priority Scheduling assigns processes a priority, executing the highest priority
process first. It can be preemptive or non-preemptive. Preemptive Priority Scheduling
switches to a higher priority process if one arrives, while Non-preemptive Priority Scheduling
lets the current process finish. It's used in real-time systems but may cause starvation for
low priority processes. Dynamic priority adjustments can address this issue.

Program code :-

/*
Name:Navadeep
Satheesh
Roll no:49
Date: 22-3-2024
To implement menu driven cpu scheduling with atleast 5 process
(a) FCFS
(b) Round Robin
(c) SJF
(d) Priority

*/
#include <stdio.h>
typedef struct //to store details related to a process
{
int pid;
int arrival;
int burst;
int completion;
int turnaround;
int waiting;
int remaining;
int priority;
} process;

typedef struct //to store data to make gantt chart


{
int pid;
int start;
int burst;
} pstat;

int front = -1, rear = -1, queue[100]; // for ready queue

26
void enqueue(int item) // functon to insert process into queue
{
if (rear == -1)
front = rear = 0;
else if (rear != 100)
rear++;
queue[rear] = item;
}

int dequeue() // function to remove process from queue


{
int item = queue[front];
if (front == -1)
return -1;
if (front == rear)
front = rear = -1;
else
front++;
return item;
}

//functon to sort the process according to arrival time and by process id


void sortprocess(process p[], int n, int ch)
{
int i, j, swap = 0;
process temp;
for (i = 0; i < n; i++)
{
for (j = 0; j < n - i - 1; j++)
{
if (ch == 0 && p[j + 1].arrival < p[j].arrival)
{
temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
swap = 1;
}
else if (ch == 1 && p[j + 1].pid < p[j].pid)
{
temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
swap = 1;
}

27
}
if (swap == 0)
break;
}
}

void gantt(pstat[], int);


void fcfs(process[], int);
void roundrobin(process[], int, int);
void sjf(process[], int);
void priority(process[], int);
void display(process[], int);

int main()
{
int n, c = 1, ch, t, i, j, swap = 0;
process p[25];
printf("Enter the number of processes: ");
scanf("%d", &n);
printf("Enter the process id, arrival time and burst time: \n");
for (i = 0; i < n; i++)
scanf("%d%d%d", &p[i].pid, &p[i].arrival, &p[i].burst);
sortprocess(p, n, 1);
sortprocess(p, n, 0);
printf("[0]\tExit\n[1]\tFCFS\n[2]\tRound Robin\n[3]\tSJF\n[4]\tPriority\n");
while (c)
{
printf("Enter your choice: ");
scanf("%d", &ch);
switch (ch)
{
case 0:
c = 0;
break;
case 1:
fcfs(p, n);
break;
case 2:
printf("Enter the time quantum: ");
scanf("%d", &t);
roundrobin(p, n, t);
break;
case 3:
sjf(p, n);

28
break;
case 4:
priority(p, n);
break;
default:
printf("Invalid input\n");
}
}
return 0;
}

//function to show gantt chart


void gantt(pstat p[], int n)
{
int i, j, t = 0;
char hl[] = "\u2500", vl[] = "\u2502";
char dr[] = "\u250C", dl[] = "\u2510", ur[] = "\u2514", ul[] = "\u2518";
char dh[] = "\u252C", uh[] = "\u2534";
printf("\nGANTT CHART\n");
for (i = 0; i < n; i++)
{
if (i == 0)
printf("%s", dr);
if (p[i].start != t)
{
for (j = 0; j < 4; j++)
printf("%s", hl);
t += (p[i].start - t);
printf("%s", dh);
}
for (j = 0; j < 2 * p[i].burst; j++)
printf("%s", hl);
t += p[i].burst;
if (i != n - 1)
printf("%s", dh);
else
printf("%s", dl);
}
printf("\n");
t = 0;
for (i = 0; i < n; i++)
{
printf("%s", vl);
if (p[i].start != t) // handle idle condition

29
{
printf("IDLE");
t += (p[i].start - t);
printf("%s", vl);
}
for (j = 0; j < p[i].burst - 1; j++)
printf(" ");
printf("P%d", p[i].pid);
for (j = 0; j < p[i].burst - 1; j++)
printf(" ");
t += p[i].burst;
}
printf("%s\n", vl);
t = 0;
for (i = 0; i < n; i++)
{
if (i == 0)
printf("%s", ur);
if (p[i].start != t)
{
for (j = 0; j < 4; j++)
printf("%s", hl);
t += (p[i].start - t);
printf("%s", uh);
}
for (j = 0; j < 2 * p[i].burst; j++)
printf("%s", hl);
t += p[i].burst;
if (i != n - 1)
printf("%s", uh);
else
printf("%s", ul);
}
printf("\n");
t = 0;
for (i = 0; i < n; i++)
{
if (t != p[i].start)
{
printf("%d", t);
for (j = 0; j < 4; j++)
printf(" ");
printf("%d", p[i].start);
t += (p[i].start - t);

30
}
else
printf("%d", t);
if (t % 100 < 10)
for (j = 0; j < 2 * p[i].burst; j++)
printf(" ");
else
for (j = 0; j < 2 * p[i].burst - 1; j++)
printf(" ");
t += p[i].burst;
}
printf("%d\n\n", t);
}

void display(process p[], int n) //function to display the corresponding data about the
//process
{
int i;
double avgwt = 0, avgtt = 0;
sortprocess(p, n, 1);

printf("=====================================================================
======================\n");

printf("ProcessId\tArrivalTime\tBurstTime\tCompletionTime\tTurnAroundTime\tWaitingTim
e\n");

printf("=====================================================================
======================\n");
for (i = 0; i < n; i++)
printf("%-12d\t%-12d\t%-10d\t%-15d\t%-15d\t%-12d\n", p[i].pid, p[i].arrival, p[i].burst,
p[i].completion, p[i].turnaround = p[i].completion - p[i].arrival, p[i].waiting = p[i].completion
- p[i].arrival - p[i].burst);

printf("=====================================================================
======================\n");
for (i = 0; i < n; i++)
{
avgtt += p[i].turnaround;
avgwt += p[i].waiting;
}
avgtt = avgtt / n;
avgwt = avgwt / n;
printf("Average TurnAround Time: %f\n", avgtt);

31
printf("Average Waiting Time: %f\n", avgwt);
}

void fcfs(process p[], int n) // function for fcfs sheduling


{
int t = 0, i = 0, j, temp, count = 0;
pstat ps[50];
while (count != n)
{
if (t >= p[count].arrival)
{
ps[count].pid = p[count].pid;
ps[count].start = t;
ps[count].burst = p[count].burst;
t += p[count].burst;
p[count].completion = t;
count++;
}
else
t++;
}
gantt(ps, count);
display(p, n);
}

void roundrobin(process p[], int n, int qt) //function for round robin scheduling
{
int i = 0, j, t = p[0].arrival, flag, cp, count = 0, gc = 0;
pstat ps[50];
front = rear = -1;
for (i = 0; i < n; i++)
{
p[i].remaining = p[i].burst; //adding the burst time as remaining time initially
if (t == p[i].arrival)
enqueue(i); //adding process to ready queue if i th process arrived at time t
}
while (count < n)
{
cp = dequeue();
if (cp != -1)
{
ps[gc].pid = p[cp].pid;
ps[gc].start = t;
if (p[cp].remaining > qt) // execute if remaining time is greater than time slice

32
{
ps[gc].burst = qt;
t += qt;
p[cp].remaining -= qt;
for (i = 0; i < n; i++)
{
flag = 0;
if (t >= p[i].arrival && p[i].remaining > 0 && i != cp)
{
for (j = front; j <= rear; j++)
if (queue[j] == i)
flag = 1;
if (flag == 0)
enqueue(i);
}
}
enqueue(cp);
}
else
// execute if remaining time is less than time slice
{
ps[gc].burst = p[cp].remaining;
t += p[cp].remaining;
p[cp].completion = t;
p[cp].remaining = 0;
count++;
}
gc++;
}
else
{
while (front == -1)
{
for (i = 0; i < n; i++)
{
if (t >= p[i].arrival && p[i].remaining > 0)
{
enqueue(i);
}
}
if (front == -1)
t++;
}
}

33
}
gantt(ps, gc);
display(p, n);
}
//function for short job first sheduling
void sjf(process p[], int n)
{
int t = 0, count = 0, cp, i, minBurstTime;
pstat ps[50];
for (i = 0; i < n; i++)
p[i].remaining = p[i].burst;
while (count != n)
{
cp = -1;
minBurstTime = 9999;
// to find process with shortest burst time at time t
for (i = 0; i < n; i++)
{
if ((p[i].arrival <= t) && (p[i].remaining > 0) && (p[i].remaining < minBurstTime))
{
minBurstTime = p[i].remaining;
cp = i;
}
}
if (cp != -1)
{
ps[count].pid = p[cp].pid;
ps[count].start = t;
ps[count].burst = p[cp].burst;
t += p[cp].burst;
p[cp].remaining = 0;
p[cp].completion = t;
count++;
}
else
t++;
}
gantt(ps, count);
display(p, n);
}
// function for priority sheduling
void priority(process p[], int n)
{
int t = 0, count = 0, cp, i, prior;

34
pstat ps[50];
printf("Enter the priorities of all the processes: \n"); //read all priorities
for (i = 0; i < n; i++)
{
printf("P%d: ", p[i].pid);
scanf("%d", &p[i].priority);
p[i].remaining = p[i].burst;
}
while (count != n)
{
cp = -1;
prior = 9999;
// to find the process priority at time t
for (i = 0; i < n; i++)
{
if ((p[i].arrival <= t) && (p[i].remaining > 0) && p[i].priority < prior)
{
prior = p[i].priority;
cp = i;
}
}
if (cp != -1)
{
ps[count].pid = p[cp].pid;
ps[count].start = t;
ps[count].burst = p[cp].burst;
t += p[cp].burst;
p[cp].remaining = 0;
p[cp].completion = t;
count++;
}
else
t++;
}
gantt(ps, count);
display(p, n);
}

35
Sample output:-

36
Result: Program is compiled and executed successfully and output is obtained.

37
38
Exp no : 7 INTER PROCESS COMMUNICATION
Date : 11-04-2023

Aim : Implement programs for Inter Process Communication using Shared Memory.
Description:
Shared memory is a form of interprocess communication (IPC) that enables multiple
processes to access the same region of memory simultaneously. In this method, a
portion of memory is shared among processes, allowing them to exchange data quickly and
efficiently without the need for complex synchronization mechanisms. Processes can read
from and write to shared memory segments, enabling fast communication and data sharing.
However, careful coordination and synchronization are necessary to prevent data corruption
and ensure consistency, as there are no built-in protections against simultaneous access by
multiple processes. Despite its speed and efficiency, shared memory IPC requires careful
management of memory allocation and deallocation to avoid memory leaks and other
resource-related issues.

Program code :
Code for sender :
/*
Renjth Rajan

To implement ipc using shared memory


This is sender side code
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
void *shared_memory;
char buffer[100];
int shmid;
printf("Data written into shared memory: %s\n", (char *)shared_memory);
//create shared memory and get the id

39
shmid2 = shmget((key_t)1242, 1024, 0666 | IPC_CREAT);
printf("Key of shared memory is %d\n", shmid2);

//attach the shared memory


shared_memory2 = shmat(shmid2, NULL, 0);
printf("Enter some data to write into the shared memory:\n");
read(0, buffer2, 100); //read the content to store into the memory
strcpy(shared_memory2, buffer2);
return 0;
}

Code for Receiver:


/*
Navadeep
Satheesh
Date-
To implement ipc using shared memory
This is reciver side code
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
void *shared_memory;
char buffer[100];
int shmid;
//get the id of the shared memory
shmid = shmget((key_t)1242, 1024, 0666);
printf("Key of shared memory is %d\n", shmid);
//attach to the share memory using shmid
shared_memory=shmat(shmid,NULL,0);
printf("data shared from memory is : %s\n",(char*)shared_memory);
return 0;
}

40
Description:
In this program, we declare two arrays of threads: one for producers and one for
consumers. We also declare a mutex variable named `mutex` to control access to the
critical section, which is the buffer array where data is written and read. Additionally, we
declare two counting semaphores: `empty`, which tracks the number of empty locations in
the buffer, and `full`, which tracks the number of occupied locations in the buffer. The
`sem_wait()` system call is equivalent to the `wait()` function, and `sem_post()` is equivalent
to the `signal()` function. These semaphores ensure synchronized access to the buffer,
preventing race conditions between producers and consumers.

Program code:

#include <pthread.h>
#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#define buffer_size 2
#define maxItem 2

41
sem_t empty;
sem_t full;
int in = 0, out = 0;
int buffer[buffer_size];
pthread_mutex_t mutex;

void *producer(void *pno) { // function for producer


int item, i;
for (i = 0; i < maxItem; i++)
{
item = rand(); //produce item
sem_wait(&empty); //insert only if buffer has empty space
pthread_mutex_lock(&mutex);
buffer[in] = item;
printf("Producer %d: Inserted item %d at %d\n", *((int *)pno), buffer[in], in);
in = (in + 1) % buffer_size;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
}

void *consumer(void *cno) { //function for consumer


int i;
for (i = 0; i < maxItem; i++) {
sem_wait(&full); // consume if full is not empty
pthread_mutex_lock(&mutex);
int item = buffer[out];
printf("Consumer %d: Removed item %d from %d\n", *((int *)cno), item, out);
out = (out + 1) % buffer_size;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
}

int main() {
int i;
pthread_t pro[buffer_size], con[buffer_size];
pthread_mutex_init(&mutex, NULL);
sem_init(&empty, 0, buffer_size);
sem_init(&full, 0, 0);

int a[]={1,2,3,4,5};

42
for (i = 0; i < buffer_size; i++) { //create producer thread
pthread_create(&pro[i], NULL, producer, (void *)&a[i]);
}

for (i = 0; i < buffer_size; i++) { //create consumer thread


pthread_create(&con[i], NULL, consumer, (void *)&a[i]);
}

for (i = 0; i < buffer_size; i++) {


pthread_join(pro[i], NULL);
}

for (i = 0; i < buffer_size; i++) {


pthread_join(con[i], NULL);
}
//destroy the semaphore created
pthread_mutex_destroy(&mutex);
sem_destroy(&empty);
sem_destroy(&full);

return 0;
}
Program code:
/*
Renjth Rajan
Roll no- 49 data-29-04-2024
To solve the dinning philosophers problem using semaphore.
*/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

43
sem_t room; // create semaphores
sem_t chopstick[5];

void *philosopher(void *);


void eat(int);

int main()
{
int i, a[5];
pthread_t tid[5];
sem_init(&room, 0, 4); // initialize samaphore
for (i = 0; i < 5; i++)
sem_init(&chopstick[i], 0, 1);
for (i = 0; i < 5; i++) //create thread for philosopher
{
a[i] = i;
pthread_create(&tid[i], NULL, philosopher, (void *)&a[i]);
}
for (i = 0; i < 5; i++)
pthread_join(tid[i], NULL);
return 0;
}

void *philosopher(void *num)


{
int phil = *(int *)num;
sem_wait(&room);
printf("\nPhilosopher %d started thinking ", phil);
sem_wait(&chopstick[phil]);
sem_wait(&chopstick[(phil + 1) % 5]);
printf("\nPhilosopher %d stopped thinking ", phil);
printf("\nPhilosopher %d is eating ", phil);
sleep(2);
printf("\nPhilosopher %d has finished eating ", phil);
sem_post(&chopstick[(phil + 1) % 5]);
sem_post(&chopstick[phil]);
sem_post(&room);
pthread_exit(NULL);
}

void eat(int phil)


{
printf("\nPhilosopher %d is eating ", phil);
}

44
45

You might also like