0% found this document useful (0 votes)
8 views

OS_Lab

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

OS_Lab

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

Department of Information Technology

EIT51002 - OPERATING SYSTEM LAB

Hindustan Institute of Technology & Sciences


Operating System Lab
List of Experiments
1. Basic Linux Commands
2. Write programs using the following system calls of UNIX operating system fork, exec, getpid,
exit, wait, close, stat, opendir, readdir.
3. Write and execute C programs to implement the various CPU scheduling Algorithms.
4. Implementation of Semaphores.
5. Implementation of the following Memory Allocation Methods for fixed partition: a) First Fit
b)worst fit c) best fit
6. Implementation of Paging Technique of Memory Management.
7. Implementation of the various File Organization Techniques.
8. Implementation of the following File Allocation Strategies: a) Sequential b) Indexed c) Linked
9. Implementation of various Disk scheduling Algorithm.
Ex. No. 1 Basic Linux Commands

Aim: To write all linux commands and execute

Description:

Command Description Options Examples

 ls -l
 -l: Long format listing. displays files and directories with detailed
List files and directories.  -a: Include hidden files information.
hidden ones  ls -a
 -h: Human-readable file shows all files and directories, including
ls sizes.  ls -lh
displays file sizes in a human-readable format.

cd Change directory.  cd /path/to/directory


changes the current directory to the specified path.

pwd Print current working directory.  pwd


displays the current working directory.

mkdir Create a new directory.  mkdir my_directory


creates a new directory named “my_directory”.

 rm file.txt
deletes the file named “file.txt”.
 -r: Remove directories  rm -r my_directory
Remove files and directories. recursively. deletes the directory “my_directory” and its
 -f: Force removal without contents.
confirmation.  rm -f file.txt
rm forcefully deletes the file “file.txt” without
confirmation.

 cp -r directory destination
copies the directory “directory” and its contents to
Copy files and directories.  -r: Copy directories the specified destination.
recursively.
cp  cp file.txt destination
copies the file “file.txt” to the specified destination.

 mv file.txt new_name.txt
Move/rename files and directories. renames the file “file.txt” to “new_name.txt”.
mv  mv file.txt directory
moves the file “file.txt” to the specified directory.

Create an empty file or update file


touch timestamps.  touch file.txt
creates an empty file named “file.txt”.

cat View the contents of a file.  cat file.txt


displays the contents of the file “file.txt”.

 head file.txt
Display the first few lines of a file.  -n: Specify the number of shows the first 10 lines of the file “file.txt”.
head lines to display.  head -n 5 file.txt
displays the first 5 lines of the file “file.txt”.

tail Display the last few lines of a file.  -n: Specify the number of  tail file.txt
lines to display. shows the last 10 lines of the file “file.txt”.
Command Description Options Examples

 tail -n 5 file.txt
displays the last 5 lines of the file “file.txt”.

Create links between files.  -s: Create symbolic (soft)


 ln -s source_file link_name
ln creates a symbolic link named “link_name” pointing
links.
to “source_file”.

Search for files and directories.  -name: Search by filename.  find /path/to/search -name “*.txt”
find searches for all files with the extension “.txt” in the
 -type: Search by file type. specified directory.
2. File Permission Commands
File permissions on Linux and Unix systems control access to files and directories. There are three basic permissions: read, write, and execute.
Each permission can be granted or denied to three different categories of users: the owner of the file, the members of the file’s group, and
everyone else.
Here are some file permission commands:
Command Description Options Examples

 u: User/owner
permissions.
 g: Group
permissions.
Change file
permissions.
 o: Other permissions. chmod u+rwx file.txt
 +: Add permissions. grants read, write, and execute permissions to the owner of the file.
 –: Remove
permissions.
chmod  =: Set permissions
explicitly.

chown Change file ownership.  chown user file.txt


changes the owner of “file.txt” to the specified user.

Change group
chgrp ownership.  chgrp group file.txt
changes the group ownership of “file.txt” to the specified group.

Set default file  umask 022


umask permissions. sets the default file permissions to read and write for the owner, and
read-only for group and others.

3. File Compression and Archiving Commands


Here are some file compression and archiving commands in Linux:
Commands Description Options Examples

 -c: Create a new archive.


 -x: Extract files from an
archive.
 -f: Specify the archive
Create or extract archive
file name.  tar -czvf archive.tar.gz files/
files. creates a compressed tar archive named “archive.tar.gz” containing
 -v: Verbose mode. the files in the “files/” directory.
 -z: Compress the archive
with gzip.
tar  -j: Compress the archive
with bzip2.

gzip Compress files.


 -d: Decompress files.
 gzip file.txt
compresses the file “file.txt” and renames it as “file.txt.gz”.
Commands Description Options Examples

Create compressed zip


 -r: Recursively include
 zip archive.zip file1.txt file2.txt
zip archives. creates a zip archive named “archive.zip” containing “file1.txt” and
directories.
“file2.txt”.
4. Process Management Commands
In Linux, process management commands allow you to monitor and control running processes on the system. Here are some commonly used
process management commands:
Commands Description Options Examples

 ps aux
Display running processes. shows all running processes with
ps  -aux: Show all processes.
detailed information.

Monitor system processes in real-time.  top


top displays a dynamic view of system
processes and their resource usage.

Terminate a process.  kill PID


kill  -9: Forcefully kill a process. terminates the process with the
specified process ID.

Terminate processes based on their name.  pkill process_name


pkill terminates all processes with the
specified name.

 pgrep process_name
List processes based on their name. lists all processes with the specified
pgrep name.

 -i: Ignore case distinctions


while searching.
 -v: Invert the match,
displaying non-matching
lines.
 -r or -R: Recursively search
directories for matching
patterns.
 -l: Print only the names of
 grep -i “hello” file.txt
files containing matches.
 -n: Display line numbers
 grep -v “error” file.txt
used to search for specific patterns or regular
alongside matching lines.  grep -r “pattern” directory/
expressions in text files or streams and display
matching lines.  -w: Match whole words only,  grep -l “keyword” file.txt
rather than partial matches.  grep -n “pattern” file.txt
 -c: Count the number of In these examples we are extracting
matching lines instead of our desirec output from filename
displaying them. (file.txt)
 -e: Specify multiple patterns
to search for.
 -A: Display lines after the
matching line.
 -B: Display lines before the
matching line.
grep  -C: Display lines both before
and after the matching line.
5. System Information Commands
In Linux, there are several commands available to gather system information. Here are some commonly used system information commands:
sudCommand Description Options Examples
sudCommand Description Options Examples

uname Print system information.  -a: All system  uname -a


information. displays all system information.

whoami Display current username.  whoami


shows the current username.

Show disk space usage.  -h: Human-readable


 df -h
df displays disk space usage in a human-readable
sizes.
format.

 -h: Human-readable
Estimate file and directory sizes. sizes.  du -sh directory/
du  -s: Display total size provides the total size of the specified directory.
only.

Display memory usage information. -h: Human-readable


 free -h
free displays memory usage in a human-readable
sizes.
format.

uptime Show system uptime.  uptime


shows the current system uptime.

Display CPU information.  lscpu


lscpu provides detailed CPU information.

lspci List PCI devices.  lspci


List PCI devices.

List USB devices.  lsusb


lsusb lists all connected USB devices.

6. Networking Commands
In Linux, there are several networking commands available to manage and troubleshoot network connections. Here are some commonly used
networking commands:
Command Description Examples

ifconfig Display network interface information.  ifconfig


shows the details of all network interfaces.

Send ICMP echo requests to a host.  ping google.com


ping sends ICMP echo requests to “google.com” to check
connectivity.

netstat Display network connections and statistics. netstat -tuln


shows all listening TCP and UDP connections.

Display network socket information.  ss -tuln


ss shows all listening TCP and UDP connections.

ssh Securely connect to a remote server.  ssh user@hostname


initiates an SSH connection to the specified hostname.

scp Securely copy files between hosts.  scp file.txt user@hostname:/path/to/destination


securely copies “file.txt” to the specified remote host.
Command Description Examples

wget Download files from the web.  wget http://example.com/file.txt


downloads “file.txt” from the specified URL.

curl Transfer data to or from a server.  curl http://example.com


retrieves the content of a webpage from the specified URL.
7. IO Redirection Commands
In Linux, IO (Input/Output) redirection commands are used to redirect the standard input, output, and error streams of commands and
processes. Here are some commonly used IO redirection commands:
Command Description

cmd < file Input of cmd is taken from file.

cmd > file Standard output (stdout) of cmd is redirected to file.

cmd 2> file Error output (stderr) of cmd is redirected to file.

cmd 2>&1 stderr is redirected to the same place as stdout.

cmd1 <(cmd2) Output of cmd2 is used as the input file for cmd1.

cmd > /dev/null Discards the stdout of cmd by sending it to the null device.

cmd &> file Every output of cmd is redirected to file.

cmd 1>&2 stdout is redirected to the same place as stderr.

cmd >> file Appends the stdout of cmd to file.

8. Environment Variable Commands


In Linux, environment variables are used to store configuration settings, system information, and other variables that can be accessed by
processes and shell scripts. Here are some commonly used environment variable commands:
Command Description

export VARIABLE_NAME=value Sets the value of an environment variable.

echo $VARIABLE_NAME Displays the value of a specific environment variable.

env Lists all environment variables currently set in the system.

unset VARIABLE_NAME Unsets or removes an environment variable.

export -p Shows a list of all currently exported environment variables.


Command Description

env VAR1=value COMMAND Sets the value of an environment variable for a specific command.

printenv Displays the values of all environment variables.

9. User Management Commands


In Linux, user management commands allow you to create, modify, and manage user accounts on the system. Here are some commonly used
user management commands:
Command Description

who Show who is currently logged in.

sudo adduser username Create a new user account on the system with the specified username.

Display information about all the users currently logged into the system, including their usernames,
finger
login time, and terminal.

sudo deluser USER GROUPNAME Remove the specified user from the specified group.

last Show the recent login history of users.

Provide information about the specified user, including their username, real name, terminal, idle
finger username
time, and login time.

Delete the specified user account from the system, including their home directory and associated
sudo userdel -r username
files. The -r option ensures the removal of the user’s files.

sudo passwd -l username Lock the password of the specified user account, preventing the user from logging in.

su – username Switch to another user account with the user’s environment.

sudo usermod -a -G GROUPNAME Add an existing user to the specified group. The user is added to the group without removing them
USERNAME from their current groups.
Ex. No. 1b System Calls

Aim: To write a C program for system calls.

Description:

fork()-
It is used by processes to create the processes that are copies of themselves. With the help of such system calls, the child process can be created by the
parent process. Until the child process is executed completely, the parent process is suspended.

Some of the important points on fork() are as follows.

The parent will get the child process ID with non-zero value.
Zero Value is returned to the child.
If there will be any system or hardware errors while creating the child, -1 is returned to the fork().
With the unique process ID obtained by the child process, it does not match the ID of any existing process group.

exec()-
The exec() is such a system call that runs by replacing the current process image with the new process image. However, the original process remains as
a new process but the new process replaces the head data, stack data,etc. It runs the program from the entry point by loading the program into the
current process space.

exit()-
exit() system call, all the resources used in the process are retrieved by the operating system and then terminate the process. The system call Exit()
is equivalent to exit().

Sample Source:
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>

int main(int argc, char **argv)


{
pid_t pid;
pid = fork();
if(pid==0)
{
printf("It is the child process and pid is %d\n",getpid());
printf("I am the child.");
execl("/bin/ls", "ls", "-l", "/home/ubuntu/", (char *) 0);
perror("In exec(): ");
exit(0);
}
else if(pid > 0)
{
printf("I am the parent, and the child is %d.\n", pid);
pid = wait(&status);
printf("End of process %d: ", pid);
printf("It is the parent process and pid is %d\n",getpid());
}
if (WIFEXITED(status)) {
printf("The process ended with exit(%d).\n", WEXITSTATUS(status));
}

if (WIFSIGNALED(status)) {
printf("The process ended with kill -%d.\n", WTERMSIG(status));
}
}
if (pid < 0) {
perror("In fork():");
}
else if(pid > 0)
{

printf("It is the parent process and pid is %d\n",getpid());


int status;
wait(&status);
printf("Child is reaped\n");
}
else
{
printf("Error while forking\n");
exit(EXIT_FAILURE);
}
return 0;
}

opendir(), closedir(), readdir() and dirent system call-


Different file system types may have different directory entries. The dirent structure defines a file system independent directory entry, which contains
information common to directory entries in different file system types. A set of these structures is returned by the getdents(2) system call.

The dirent structure is defined as:

#include<sys/dirent.h>

struct dirent
{
long d_ino; /* inode number */
off_t d_off; /* offset to the next dirent */
unsigned short d_reclen; /* length of this record */
unsigned char d_type; /* type of file */
char d_name[256]; /* filename*/
};

d_ino ….. inode number of a file


d_offset ….. offset of that directory entry in the actual file system directory
d_name ….. name of the file or directory
d_reclen record length of this entry
d_type ….. type of file( text file, block file, directory etc)

/* Unix program to read all text files from a directory */


/printfile.c*/
#include<stdio.h>
#include<dirent.h>
#include<stdlib.h>
void main()
{
DIR *dirp;
struct dirent *dp;
if((dirp=opendir("/home/kumar"))==NULL) /* trying to open kumar directory*/
{
printf("\n cannot open");
exit(1);
}
for(dp=readdir(dirp);dp!=NULL;dp=readdir(dirp))
{
if(dp->d_type==DT_REG) /* printing only if file is a text file */
printf("%s\n",dp->d_name);
}
closedir(dirp);
}
Ex. No. 2a Process Scheduling and Synchronization

Aim: To write and execute C program to implement the various CPU Scheduling Algorithm.

Description:
1. Initialize two array pid[] and bt[] of size 15.
2. Ask the user for number of processes n.
3. Ask the user for process id and burst time for all n processes and store them into pid[] and bt[] respectively.
4. Calculate waiting time of each process by the formula wt[i] = wt[i-1] + bt[i-1].
5. Print Process Id, Burst Time, waiting time and Turnaround time of each process in tabular manner.
6. Calculate and print turnaround time of each process = bt[i] + wt[i].
7. Add waiting time of all the processes and store it in the variable twt.
8. Add turnaround time of all the processes and store it in the variable tat.
9. Calculate average waiting time as awt = twt/n.
10. Calculate average turnaround time as att = tat/n;
11. Print average waiting time and average turnaround time.
12. Exit.

FCFS Scheduling Algorithm:


The CPU scheduling algorithm First Come, First Served (FCFS), also known as First In, First Out (FIFO), allocates the CPU to the processes in the order they are queued in the
ready queue.
FCFS uses non-preemptive scheduling, which means that once a CPU has been assigned to a process, it stays assigned to that process until it is either not terminated or may
be interrupted by an I/O interrupt.

Problem Solution
1. Enter all the processes and their burst time.
2. Find waiting time, WT of all the processes.
3. For the 1st process, WT = 0.
4. For all the next processes i, WT[i] = BT[i-1] + WT[i-1].
5. Calculate Turnaround time = WT + BT for all the processes.
6. Calculate average waiting time = total waiting time/no. of processes.
7. Calculate average turnaround time = total turnaround time/no. of processes.
Example:

Process Arrival Time Burst Time

P1 0 5

P2 0 11

P3 0 11

Waiting Time: Time Difference between turnaround time and burst time.
Waiting Time = Turnaround Time – Burst Time
P1 waiting time: 0
P2 waiting time: 5
P3 waiting time: 16

Average Waiting Time = (0 + 5 + 16)/3 = 21/3 = 7

Turnaround Time: Difference between completion time and arrival time.


Turnaround Time = Completion Time – Arrival Time
P1 turnaround time: 5-0 = 5
P2 turnaround time: 16-0 = 16
P3 turnaround time: 27-0 = 27

Average Turnaround Time = (5+16+27)/3 = 16

Program/Source Code:

1. #include <stdio.h>
2. int main()
3. {
4. int pid[15];
5. int bt[15];
6. int n;
7. printf("Enter the number of processes: ");
8. scanf("%d",&n);
9.
10. printf("Enter process id of all the processes: ");
11. for(int i=0;i<n;i++)
12. {
13. scanf("%d",&pid[i]);
14. }
15.
16. printf("Enter burst time of all the processes: ");
17. for(int i=0;i<n;i++)
18. {
19. scanf("%d",&bt[i]);
20. }
21.
22. int i, wt[n];
23. wt[0]=0;
24.
25. //for calculating waiting time of each process
26. for(i=1; i<n; i++)
27. {
28. wt[i]= bt[i-1]+ wt[i-1];
29. }
30.
31. printf("Process ID Burst Time Waiting Time TurnAround
Time\n");
32. float twt=0.0;
33. float tat= 0.0;
34. for(i=0; i<n; i++)
35. {
36. printf("%d\t\t", pid[i]);
37. printf("%d\t\t", bt[i]);
38. printf("%d\t\t", wt[i]);
39.
40. //calculating and printing turnaround time of each process
41. printf("%d\t\t", bt[i]+wt[i]);
42. printf("\n");
43.
44. //for calculating total waiting time
45. twt += wt[i];
46.
47. //for calculating total turnaround time
48. tat += (wt[i]+bt[i]);
49. }
50. float att,awt;
51.
52. //for calculating average waiting time
53. awt = twt/n;
54.
55. //for calculating average turnaround time
56. att = tat/n;
57. printf("Avg. waiting time= %f\n",awt);
58. printf("Avg. turnaround time= %f",att);
59. }
SJF:
Program Explanation
1. Initialize two array pid[] and bt[] of size 20.
2. Ask the user for number of processes n.
3. Ask the user for process id and burst time for all n processes and store them into pid[] and bt[] respectively.
4. Sort all the processes according to their burst time.
5. Assign waiting time = 0 to the smallest process.
6. Calculate waiting time of each process by using two loops and adding all the burst time of previously completed processes.
7. Print Process Id, Burst Time, waiting time and Turnaround time of each process in tabular manner.
8. Calculate and print turnaround time of each process = bt[i] + wt[i].
9. Add waiting time of all the processes and store it in the variable total.
10. Add turnaround time of all the processes and store it in the variable totalT.
11. Calculate average waiting time as avg_wt = total/n.
12. Calculate average turnaround time as avg_tat = totalT/n;
13. Print average waiting time and average turnaround time.
14. Exit.
The CPU scheduling algorithm Shortest Job First (SJF), allocates the CPU to the processes according to the process with smallest execution time.
SJF uses both preemptive and non-preemptive scheduling. The preemptive version of SJF is called SRTF (Shortest Remaining Time First). Here we will discuss about SJF i.e.,
the non-preemptive scheduling.
Advantages of SJF:
 It has the minimum waiting time among all the scheduling algorithms.
 A process having larger burst time may get into starvation but the problem can be solved using concept of Ageing.
 It is a greedy algorithm and provides optimal scheduling.
Problem Solution
1. Enter number of processes.
2. Enter the burst time of all the processes.
3. Sort all the processes according to their burst time.
4. Find waiting time, WT of all the processes.
5. For the smallest process, WT = 0.
6. For all the next processes i, find waiting time by adding burst time of all the previously completed process.
7. Calculate Turnaround time = WT + BT for all the processes.
8. Calculate average waiting time = total waiting time / no. of processes.
9. Calculate average turnaround time= total turnaround time / no. of processes.
SJF Example:

Process Arrival Time Burst Time

P1 0 5

P2 0 4

P3 0 12

P4 0 7
Gantt Chart:

Waiting Time: Time Difference between turnaround time and burst time.
Waiting Time = Turnaround Time – Burst Time
P1 waiting time: 4
P2 waiting time: 0
P3 waiting time: 16
P4 waiting time: 9

Average Waiting Time = (4 + 0 + 16 + 9)/4 = 29/4 = 7.25

Turnaround Time: Difference between completion time and arrival time.


Turnaround Time = Completion Time – Arrival Time
P1 turnaround time: 9-0 = 9
P2 turnaround time: 4-0 = 4
P3 turnaround time: 28-0 = 28
P4 turnaround time: 16-0 = 16

Average Turnaround Time = (9 + 4 + 28 + 16)/4 = 14.25

Program/Source Code:
1. #include<stdio.h>
2. int main()
3. {
4. int bt[20],p[20],wt[20],tat[20],i,j,n,total=0,totalT=0,pos,temp;
5. float avg_wt,avg_tat;
6. printf("Enter number of process:");
7. scanf("%d",&n);
8.
9. printf("\nEnter Burst Time:\n");
10. for(i=0;i<n;i++)
11. {
12. printf("p%d:",i+1);
13. scanf("%d",&bt[i]);
14. p[i]=i+1;
15. }
16.
17. //sorting of burst times
18. for(i=0;i<n;i++)
19. {
20. pos=i;
21. for(j=i+1;j<n;j++)
22. {
23. if(bt[j]<bt[pos])
24. pos=j;
25. }
26.
27. temp=bt[i];
28. bt[i]=bt[pos];
29. bt[pos]=temp;
30.
31. temp=p[i];
32. p[i]=p[pos];
33. p[pos]=temp;
34. }
35.
36. wt[0]=0;
37.
38. //finding the waiting time of all the processes
39. for(i=1;i<n;i++)
40. {
41. wt[i]=0;
42. for(j=0;j<i;j++)
43. //individual WT by adding BT of all previous completed
processes
44. wt[i]+=bt[j];
45.
46. //total waiting time
47. total+=wt[i];
48. }
49.
50. //average waiting time
51. avg_wt=(float)total/n;
52.
53. printf("\nProcess\t Burst Time \tWaiting Time\tTurnaround Time");
54. for(i=0;i<n;i++)
55. {
56. //turnaround time of individual processes
57. tat[i]=bt[i]+wt[i];
58.
59. //total turnaround time
60. totalT+=tat[i];
61. printf("\np%d\t\t %d\t\t %d\t\t\t%d",p[i],bt[i],wt[i],tat[i]);
62. }
63.
64. //average turnaround time
65. avg_tat=(float)totalT/n;
66. printf("\n\nAverage Waiting Time=%f",avg_wt);
67. printf("\nAverage Turnaround Time=%f",avg_tat);
68. }
Priority Scheduling Algorithm:
Program Explanation
1. First, enter the total number of processes and store it in variable n.
2. After that, provide the burst time and priority and store it in variable b and p.
3. Finding out highest priority element and placing it at its desired position.
4. Sort the processes on the basis of the priority.
5. After that print the processed with their time stamp (starting time and ending time). Variable T stores the starting time of process.
6. In the end, print the waiting time and turnaround time for each process. Waiting time is the time spent in the ready queue, while turnaround time is the total time taken by
process (burst time + waiting time).

Priority Scheduling is a CPU scheduling algorithm in which the CPU performs the task having higher priority at first. If two processes have the s ame priority then scheduling is
done on FCFS basis (first come first serve). Priority Scheduling is of two types : Preemptive and Non-Preemptive.
Preemptive: In this case, resources can be voluntarily snatched.
Non-Preemptive: In this type, if a process is once started, it will execute completely i.e resources cannot be snatched.
Following are the basic terminologies:
Waiting Time: Time for which the process has to wait in the ready queue.
Turn Around Time: Total time taken by the process for execution (waiting time + burst time).

Problem Description:
Write a C Program to implement priority scheduling.
Step 1: Start the Program.
Step 2: Input the number of processes.
Step 3: Input the burst time and priority for each process.
Step 4: Sort the element on the basis of priority.
Step 5: Print order of execution of their process with their time stamp (wait time and turnaround time).
Step 6: End the Program.
Example:
Following is the example of non preemptive scheduling with arrival time zero.
Process Burst Time Priority

P1 5 1

P2 7 6

P3 2 4

P4 3 5

Since scheduling is non preemptive, which means that the process will be fully executed once its execution is started. So processes will be executed in the same order of
priority.
Order: P2, P4, P3, P1
P2 will be executed from 0 to 7.
P4 will be executed from 7 to 10.
P3 will be executed from 10 to 12.
P1 will be executed from 12 to 17.

Process Id Burst Time Wait Time Turn Around Time

P2 7 0 7

P4 3 7 10

P3 2 10 12

P1 5 12 17

Program/Source Code
Here is the source code of the C program to implement priority scheduling. The C program is successfully compiled and run on a Linux system. The program output is also
shown below.

1. #include <stdio.h>
2.
3. //Function to swap two variables
4. void swap(int *a,int *b)
5. {
6. int temp=*a;
7. *a=*b;
8. *b=temp;
9. }
10. int main()
11. {
12. int n;
13. printf("Enter Number of Processes: ");
14. scanf("%d",&n);
15.
16. // b is array for burst time, p for priority and index for process
id
17. int b[n],p[n],index[n];
18. for(int i=0;i<n;i++)
19. {
20. printf("Enter Burst Time and Priority Value for Process %d:
",i+1);
21. scanf("%d %d",&b[i],&p[i]);
22. index[i]=i+1;
23. }
24. for(int i=0;i<n;i++)
25. {
26. int a=p[i],m=i;
27.
28. //Finding out highest priority element and placing it at its
desired position
29. for(int j=i;j<n;j++)
30. {
31. if(p[j] > a)
32. {
33. a=p[j];
34. m=j;
35. }
36. }
37.
38. //Swapping processes
39. swap(&p[i], &p[m]);
40. swap(&b[i], &b[m]);
41. swap(&index[i],&index[m]);
42. }
43.
44. // T stores the starting time of process
45. int t=0;
46.
47. //Printing scheduled process
48. printf("Order of process Execution is\n");
49. for(int i=0;i<n;i++)
50. {
51. printf("P%d is executed from %d to %d\n",index[i],t,t+b[i]);
52. t+=b[i];
53. }
54. printf("\n");
55. printf("Process Id Burst Time Wait Time TurnAround
Time\n");
56. int wait_time=0;
57. for(int i=0;i<n;i++)
58. {
59. printf("P%d %d %d
%d\n",index[i],b[i],wait_time,wait_time + b[i]);
60. wait_time += b[i];
61. }
62. return 0;
63. }

Time Complexity: O(n*n)


Sorting takes time of the order of O(n*n), So time complexity is of the order of O(n*n).
Space Complexity: O(n)
Space is required to store burst time, arrival time and index, So space complexity is O(n).

Round Robin Scheduling is a CPU scheduling algorithm in which each process is executed for a fixed time slot. Since the resources are snatched after the time slot, round
robin is preemptive.
Preemptive: In this type, resources can be voluntarily snatched.
Non-Preemptive: In this type, if a process is once started, it will execute completely i.e resources cannot be snatched.
Following are the basic terminologies:

Turnaround Time: Difference between completion time and arrival time.


Turnaround Time = Completion Time – Arrival Time
Waiting Time: Time Difference between turnaround time and burst time.
Waiting Time = Turnaround Time – Burst Time

Problem Solution
Round Robin Scheduling Algorithm:
Step 1: Start the Program.
Step 2: Input the number of processes.
Step 3: Input the burst time and arrival time of each process and the limit of the time slot.
Step 4: Push all processes into the ready queue according to their arrival time. Then execute each process upto time slot and push left over process in queue again for
execution.
Step 5: After a process is completely executed, print its turn around time and waiting time.
Example:
Following is the example of round robin scheduling.
Process Id Arrival Time Burst Time

P1 0 10

P2 1 8

P3 2 7
Time Slot is 5 Sec.
First P1 is executed for 5 seconds, left burst time is 5 sec
Then P2 is executed for 5 seconds, left burst time is 3 sec
Then P3 is executed for 5 seconds, left burst time is 2 sec
Then P1 is executed for 5 seconds, execution of P1 is completed.
Then P2 is executed for 3 seconds, execution of P2 is completed.
Then P1 is executed for 2 sec, execution P3 is completed.
Check this: Computer Science Books | Advanced C Programming Videos

Execution of all processes completed

Process Id Burst Time Wait Time Turn Around Time

P1 10 20 10

P2 8 22 14

P3 7 23 16

Average Waiting Time = (20 + 22 + 23)/3 = 65/3 = 21.666666


Average Turnaround Time = (10 + 14 + 16)/3 = 40/3 = 13.333333

Program Explanation
1. Ask the user for number of processes n.
2. After that, ask the user for the arrival time and burst time of each process. Also input the time quantum.
3. In the loop, if time slot is greater than left burst time, execute process and find burst time.
4. Else if burst time is greater than time slot, execute it up to time slot and again push into the queue.
5. when the execution is completed, print the process information such as turnaround time and waiting time.
Program/Source code

1. #include<stdio.h>
2.
3. int main()
4. {
5. //Input no of processed
6. int n;
7. printf("Enter Total Number of Processes:");
8. scanf("%d", &n);
9. int wait_time = 0, ta_time = 0, arr_time[n], burst_time[n],
temp_burst_time[n];
10. int x = n;
11.
12. //Input details of processes
13. for(int i = 0; i < n; i++)
14. {
15. printf("Enter Details of Process %d \n", i + 1);
16. printf("Arrival Time: ");
17. scanf("%d", &arr_time[i]);
18. printf("Burst Time: ");
19. scanf("%d", &burst_time[i]);
20. temp_burst_time[i] = burst_time[i];
21. }
22.
23. //Input time slot
24. int time_slot;
25. printf("Enter Time Slot:");
26. scanf("%d", &time_slot);
27.
28. //Total indicates total time
29. //counter indicates which process is executed
30. int total = 0, counter = 0,i;
31. printf("Process ID Burst Time Turnaround Time
Waiting Time\n");
32. for(total=0, i = 0; x!=0; )
33. {
34. // define the conditions
35. if(temp_burst_time[i] <= time_slot && temp_burst_time[i] > 0)
36. {
37. total = total + temp_burst_time[i];
38. temp_burst_time[i] = 0;
39. counter=1;
40. }
41. else if(temp_burst_time[i] > 0)
42. {
43. temp_burst_time[i] = temp_burst_time[i] - time_slot;
44. total += time_slot;
45. }
46. if(temp_burst_time[i]==0 && counter==1)
47. {
48. x--; //decrement the process no.
49. printf("\nProcess No %d \t\t %d\t\t\t\t %d\t\t\t %d",
i+1, burst_time[i],
50. total-arr_time[i], total-arr_time[i]-
burst_time[i]);
51. wait_time = wait_time+total-arr_time[i]-burst_time[i];
52. ta_time += total -arr_time[i];
53. counter =0;
54. }
55. if(i==n-1)
56. {
57. i=0;
58. }
59. else if(arr_time[i+1]<=total)
60. {
61. i++;
62. }
63. else
64. {
65. i=0;
66. }
67. }
68. float average_wait_time = wait_time * 1.0 / n;
69. float average_turnaround_time = ta_time * 1.0 / n;
70. printf("\nAverage Waiting Time:%f", average_wait_time);
71. printf("\nAvg Turnaround Time:%f", average_turnaround_time);
72. return 0;
73. }
Ex. No. 2b Process Scheduling and Synchronization

Aim: To write and execute C program to implement semaphores.

Description:

POSIX named semaphore APIs we use in this lab are shown in the below table. You can look up manual
pages for details of these functions.semaphore.cshows how to use these functions to create, operate
and remove named semaphore. Try it and make sure you understand it. Note that programs using the
POSIX semaphores API must be compiled with -pthread to link against the real-time library. So you need
compile semaphore.c like this:

Function Description
sem_open Opens/creates a named semaphore for use by a process
sem_wait lock a semaphore
sem_post unlock a semaphore
sem_close Deallocates the specified named semaphore
Removes a specified named semaphore
sem_unlink
/*semaphore.c*/
#include <fcntl.h> /* For O_* constants */
#include <sys/stat.h> /* For mode constants */
#include <semaphore.h>
#include <stdio.h>
int main(int argc, char * argv[]){
char * name = "my_semaphore";
int VALUE = 2;
sem_t * sema;
//If semaphore with name does not exist, then create it with VALUE
printf("Open or Create a named semaphore, %s, its value is %d\n", name,VALUE);
sema = sem_open(name, O_CREAT, 0666, VALUE);
//wait on semaphore sema and decrease it by 1
sem_wait(sema);
printf("Decrease semaphore by 1\n");
//add semaphore sema by 1
sem_post(sema);
printf("Add semaphore by 1\n");
//Before exit, you need to close semaphore and unlink it, when all processes have
//finished using the semaphore, it can be removed from the system using sem_unlink
sem_close(sema);
sem_unlink(name);
return 0;
}
Unnamed Semaphore
POSIX semaphores are available in two flavors: named and unnamed. They differ in how they
are created and destroyed, but otherwise work the same. Unnamed semaphores exist in memory
only and require that processes have access to the memory to be able to use the semaphores. This
means they can be used only by threads in the same process or threads in different processes that
have mapped the same memory extent into their address spaces. Named semaphores, in contrast,
are accessed by name and can be used by threads in any processes that know their names.
When we want to use POSIX semaphores within a single process, it is easier to use unnamed
semaphores. This only changes the way we create and destroy the semaphore. To create an
unnamed semaphore, we call thesem_init()function.
#
include
<
semaphore.h
>
int
sem_init
(sem_t *sem,
int
pshared,
unsigned
int
value)
;
The_pshared_argument indicates if we plan to use the semaphore with multiple processes. If we
just want to use the semaphore in a single process, then set it to zero. The_value_argument
specifies the initial value of the semaphore.
Instead of returning a pointer to the semaphore likesem_open()does, we need to declare a
variable of typesem_tand pass its address to sem_init()for initialization. After initializing
unnamed semaphore usingsem_init()function, thesem_wait()andsem_post()functions can
operate as usual.
When we are done using the unnamed semaphore, we can discard it by calling
thesem_destroy()function.
#
include
<
semaphore.h
>
int
sem_destroy
(sem_t *sem)
;
After callingsem_destroy(), we can't use any of the semaphore functions with_sem_unless we
reinitialize it by callingsem_init()again.
Ex. No. 3a Memory Allocation Methods

Aim: To write and execute C program to implement Memory allocation for fixed partition – First Fit,
worst Fit, Best Fit.

Description:

First Fit:

1- Input memory blocks with size and processes with size.


2- Initialize all memory blocks as free.
3- Start by picking each process and check if it can be assigned to current block.
4- If size-of-process <= size-of-block if yes then assign and check for next process.
5- If not then keep checking the further blocks.

Input : blockSize[] = {100, 500, 200, 300, 600};


processSize[] = {212, 417, 112, 426};
Output:
Process No. Process Size Block no.
1 212 2
2 417 5
3 112 2
4 426 Not Allocated
// C implementation of First - Fit algorithm
#include<stdio.h>

// Function to allocate memory to


// blocks as per First fit algorithm
void firstFit(int blockSize[], int m, int processSize[], int n)
{
int i, j;
// Stores block id of the
// block allocated to a process
int allocation[n];

// Initially no block is assigned to any process


for(i = 0; i < n; i++)
{
allocation[i] = -1;
}

// pick each process and find suitable blocks


// according to its size ad assign to it
for (i = 0; i < n; i++) //here, n -> number of processes
{
for (j = 0; j < m; j++) //here, m -> number of blocks
{
if (blockSize[j] >= processSize[i])
{
// allocating block j to the ith process
allocation[i] = j;

// Reduce available memory in this block.


blockSize[j] -= processSize[i];

break; //go to the next process in the queue


}
}
}

printf("\nProcess No.\tProcess Size\tBlock no.\n");


for (int i = 0; i < n; i++)
{
printf(" %i\t\t\t", i+1);
printf("%i\t\t\t\t", processSize[i]);
if (allocation[i] != -1)
printf("%i", allocation[i] + 1);
else
printf("Not Allocated");
printf("\n");
}
}

// Driver code
int main()
{
int m; //number of blocks in the memory
int n; //number of processes in the input queue
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426};
m = sizeof(blockSize) / sizeof(blockSize[0]);
n = sizeof(processSize) / sizeof(processSize[0]);

firstFit(blockSize, m, processSize, n);

return 0 ;
}

Worst Fit:

Worst Fit allocates a process to the partition which is largest sufficient among the freely available
partitions available in the main memory. If a large process comes at a later stage, then memory will not
have space to accommodate it.
1- Input memory blocks and processes with sizes.
2- Initialize all memory blocks as free.
3- Start by picking each process and find the maximum block size that can be assigned to current
process i.e., find max(bockSize[1], blockSize[2],.....blockSize[n]) > processSize[current], if found then
assign it to the current process.
5- If not then leave that process and keep checking the further processes.

Input : blockSize[] = {100, 500, 200, 300, 600};


processSize[] = {212, 417, 112, 426};
Output:
Process No. Process Size Block no.
1 212 5
2 417 2
3 112 5
4 426 Not Allocated

// C implementation of worst - Fit algorithm


#include<stdio.h>

// Function to allocate memory to blocks as per worst fit


// algorithm
void worstFit(int blockSize[], int m, int processSize[], int n)
{
int i, j;
// Stores block id of the block allocated to a
// process
int allocation[n];

// Initially no block is assigned to any process


memset(allocation, -1, sizeof(allocation));

// pick each process and find suitable blocks


// according to its size ad assign to it
for (int i=0; i<n; i++)
{
// Find the best fit block for current process
int wstIdx = -1;
for (int j=0; j<m; j++)
{
if (blockSize[j] >= processSize[i])
{
if (wstIdx == -1)
wstIdx = j;
else if (blockSize[wstIdx] < blockSize[j])
wstIdx = j;
}
}
// If we could find a block for current process
if (wstIdx != -1)
{
// allocate block j to p[i] process
allocation[i] = wstIdx;

// Reduce available memory in this block.


blockSize[wstIdx] -= processSize[i];
}
}

Printf( "\nProcess No.\tProcess Size\tBlock no.\n");


for (int i = 0; i < n; i++)
{
Printf(“%d%d”, i+1, processSize[i]);
if (allocation[i] != -1)
printf(“%d”,allocation[i] + 1);
else
printf("Not Allocated");
cout << endl;
}
}

// Driver code
int main()
{
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426};
int m = sizeof(blockSize)/sizeof(blockSize[0]);
int n = sizeof(processSize)/sizeof(processSize[0]);

worstFit(blockSize, m, processSize, n);

return 0 ;
}

Best fit:
Best fit allocates the process to a partition which is the smallest sufficient partition among the free available partitions.
Example:
1- Input memory blocks and processes with sizes.
2- Initialize all memory blocks as free.
3- Start by picking each process and find the
minimum block size that can be assigned to
current process i.e., find min(bockSize[1],
blockSize[2],.....blockSize[n]) >
processSize[current], if found then assign
it to the current process.
5- If not then leave that process and keep checking
the further processes.

Input : blockSize[] = {100, 500, 200, 300, 600};


processSize[] = {212, 417, 112, 426};
Output:
Process No. Process Size Block no.
1 212 4
2 417 2
3 112 3
4 426 5

// C implementation of Best - Fit algorithm


#include<stdio.h>
// Method to allocate memory to blocks as per Best fit algorithm
void bestFit(int blockSize[], int m, int processSize[], int n)
{
int i,j;
// Stores block id of the block allocated to a process
int allocation[n];

// Initially no block is assigned to any process


for (int i = 0; i < n; i++)
allocation[i] = -1;

// pick each process and find suitable blocks


// according to its size ad assign to it
for (int i = 0; i < n; i++)
{
// Find the best fit block for current process
int bestIdx = -1;
for (int j = 0; j < m; j++)
{
if (blockSize[j] >= processSize[i])
{
if (bestIdx == -1)
bestIdx = j;
else if (blockSize[bestIdx] > blockSize[j])
bestIdx = j;
}
}

// If we could find a block for current process


if (bestIdx != -1)
{
// allocate block j to p[i] process
allocation[i] = bestIdx;

// Reduce available memory in this block.


blockSize[bestIdx] -= processSize[i];
}
}

printf("\nProcess No.\tProcess Size\tBlock no.\n");


for (int i = 0; i < n; i++)
{
Printf("%d%d ", i+1,processSize[i]);
if (allocation[i] != -1)
printf(“%d”,allocation[i] + 1);
else
printf("Not Allocated\n");
}
}

// Driver Method
int main()
{
int blockSize[] = {100, 500, 200, 300, 600};
int processSize[] = {212, 417, 112, 426};
int m = sizeof(blockSize) / sizeof(blockSize[0]);
int n = sizeof(processSize) / sizeof(processSize[0]);

bestFit(blockSize, m, processSize, n);

return 0 ;
}
Ex. No. 3b Memory Management for Paging Technique

Aim: To write and execute C program to implement paging technique.

Description:

Step 1:
Read all the necessary input from the keyboard.
Step 2:
Pages – Logical memory is broken into fixed – sized blocks.
Step 3:
Frames – Physical memory is broken into fixed – sized blocks.
Step 4:
Calculate the physical address using the following
Physical address = ( Frame number * Frame size ) + offset
Step 5: Display the physical address.
Step 6: Stop .

#include<stdio.h>
#include<conio.h>
main()
{
int np,ps,i;
int *sa;
clrscr();
printf("enter how many pages\n");
scanf("%d",&np);
printf("enter the page size \n");
scanf("%d",&ps);
sa=(int*)malloc(2*np);
for(i=0;i
{
sa[i]=(int)malloc(ps);
printf("page%d\t address %u\n",i+1,sa[i]);
}
getch();
}

OUTPUT:

Enter how many pages: 5

Enter the page size: 4

Page1 Address: 1894

Page2 Address: 1902

Page3 Address: 1910

Page4 Address: 1918

Page5 Address: 1926


Ex. No. 4a File Organization Technique

Aim: To write and execute C program to implement various file organization technique.

Description:

Ex. No. 4b File Allocation Strategies

Aim: To write and execute C program to implement file allocation strategies - sequential, indexed,
linked.

Description:

Ex. No. 5a Disk Scheduling

Aim: To write and execute C program to implement Disk Scheduling Algorithm.

Description:

You might also like