0% found this document useful (0 votes)
3 views68 pages

Os Lab

The document outlines various programming tasks related to operating systems, including system calls, CPU scheduling algorithms (FCFS, SJF, Round Robin), page replacement algorithms, and memory management techniques. Each task includes a brief explanation of the algorithm or concept, followed by a sample C program implementation. Additionally, it discusses the advantages and disadvantages of the scheduling algorithms and provides example outputs for the programs.

Uploaded by

satyaaaa028
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)
3 views68 pages

Os Lab

The document outlines various programming tasks related to operating systems, including system calls, CPU scheduling algorithms (FCFS, SJF, Round Robin), page replacement algorithms, and memory management techniques. Each task includes a brief explanation of the algorithm or concept, followed by a sample C program implementation. Additionally, it discusses the advantages and disadvantages of the scheduling algorithms and provides example outputs for the programs.

Uploaded by

satyaaaa028
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

INDEX

[Link] DATE NAME OF THE PROGRAM PAGE SIGN OF THE


NO. FACULTY

1 Write a program using


System calls.

2 Write a program to
simulate FCFS Algorithm.

3 Write a program to
simulate SJF Algorithm.

4 Write a program to
simulate Round Robin
Algorithm.

5 Write a program to
simulate FIFO page
replacement Algorithm.

6 Write a program to
implement Producer
Consumer using semaphore.

7 Write a program to
simulate Deadlock
Detection.

8 Write a program to
implement Paging Memory
Management.

9 Write a program to
implement File Allocation
Technique.

10 UNIX Commands

1
1) Write a program using System calls.
System Calls:
System calls are the essential interface allowing user

programs to request services from the operating system's

kernel, like file access, process control, or hardware

management, by switching from user mode to the more

privileged kernel mode to execute protected tasks, ensuring

security and resource management.

How They Work

1. Request: A user program needs an OS service


(e.g., open(), read(), fork()).

2. Trap/Interrupt: The program executes a special


instruction (like syscall or int 0x80) to trigger a
trap.

3. Mode Switch: The CPU switches from user mode (limited


privileges) to kernel mode (full privileges).

4. Kernel Execution: The kernel identifies the system call


number, performs the requested operation (e.g., disk
access, memory allocation).

5. Return: The kernel switches back to user mode and returns


the result (data, success/failure) to the program.

Key Functions & Types

• Process
Control: fork(), exec(), exit(), wait() (create/termina
te processes).

• File Management: open(), read(), write(), close() (file


operations).

2
• Device Management: read(), write() (interact with
devices like printers, cameras).

• Information
Maintenance: gettimeofday(), set_pid() (get/set system
info).

• Communication: pipe(), socket() (inter-process


communication).

Why They're Important

• Abstraction: Hide complex hardware details from


applications.

• Security: Protect system resources by enforcing kernel-


level control.

• Portability: Provide a consistent interface across


different hardware.

• Resource Management: Allow the OS to manage shared


resources efficiently.

3
PROGRAM:
CREATE SYSTEM CALL
#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

int main() {

// Create a new file or open it

//if it exists (write-only access)

// File permissions: rw-r--r--

int fd = creat("[Link]", 0644);

if (fd == -1) {

perror("Error creating file");

return 1;

// File was successfully created

printf("File '[Link]' created successfully \n"

"File descriptor: %d\n", fd);

// Close the file descriptor

close(fd);

return 0;

4
OUTPUT:
File '[Link]' created successfully
File descriptor: 3

5
OPEN SYSTEM CALL
#include <errno.h>

#include <fcntl.h>

#include <stdio.h>

#include <unistd.h>

extern int errno;

int main() {

// If file does not have in directory

// then file [Link] is created.

int fd = open("[Link]", O_RDONLY | O_CREAT);

printf("fd = %d\n", fd);

if (fd == -1) {

// Print which type of error have in a code

printf("Error Number % d\n", errno);

// print program detail "Success or failure"

perror("Program");

return 0;

6
OUTPUT:
fd = 3

7
CLOSE SYSTEM CALL
#include <fcntl.h>

#include <stdio.h>

#include <unistd.h>

int main() {

int fd1 = open("[Link]", O_RDONLY);

if (fd1 < 0) {

perror("c1");

exit(1);

printf("opened the fd = % d\n", fd1);

// Using close system Call

if (close(fd1) < 0) {

perror("c1");

exit(1);

printf("closed the fd.\n");

8
OUTPUT:
opened the fd = 3
closed the fd.

9
2) Write a program to simulate FCFS Algorithm.
FCFS - First Come First Serve CPU Scheduling
First Come, First Serve (FCFS) is one of the simplest types
of CPU scheduling algorithms. It is exactly what it sounds
like: processes are attended to in the order in which they
arrive in the ready queue, much like customers lining up at
a grocery store.

FCFS Scheduling is a non-preemptive algorithm, meaning once


a process starts running, it cannot be stopped until it
voluntarily relinquishes the CPU, typically when it
terminates or performs I/O. This method schedules processes
in the order they arrive, without considering priority or
other factors.

How Does FCFS Work?

The mechanics of FCFS are straightforward:

1. Arrival: Processes enter the system and are placed in a


queue in the order they arrive.

2. Execution: The CPU takes the first process from the front
of the queue, executes it until it is complete, and then
removes it from the queue.

3. Repeat: The CPU takes the next process in the queue and
repeats the execution process.

This continues until there are no more processes left in the


queue.

Advantages of FCFS

• The simplest and basic form of CPU Scheduling algorithm

• Every process gets a chance to execute in the order of


its arrival. This ensures that no process is arbitrarily
prioritized over another.

10
• Easy to implement, it doesn't require complex data
structures.

• Since processes are executed in the order they arrive,


there’s no risk of starvation

• It is well suited for batch systems where the longer


time periods for each process are often acceptable.

Disadvantages of FCFS

• As it is a Non-preemptive CPU Scheduling Algorithm, FCFS


can result in long waiting times, especially if a long
process arrives before a shorter one. This is known as
the convoy effect, where shorter processes are forced to
wait behind longer processes, leading to inefficient
execution.

• The average waiting time in the FCFS is much higher than


in the others

• Since FCFS processes tasks in the order they arrive,


short jobs may have to wait a long time if they arrive
after longer tasks, which leads to poor performance in
systems with a mix of long and short tasks.

• Processes that are at the end of the queue, have to wait


longer to finish.

• It is not suitable for time-sharing operating systems


where each process should get the same amount of CPU
time.

11
Example of FCFS CPU Scheduling
Consider the following table of arrival time and burst time
for three processes P1, P2 and P3

Process Arrival Time Burst Time

p1 0 5

p2 0 3

p3 0 8

Turnaround Time = Completion Time - Arrival Time


Waiting Time = Turnaround Time - Burst Time
AT : Arrival Time
BT : Burst Time or CPU Time
TAT : Turn Around Time
WT : Waiting Time

Processes AT BT CT TAT WT

P1 0 5 5 5-0 = 5 5-5 = 0

P2 0 3 8 8-0 = 8 8-3 = 5

16-0 = 16-8 =
P3 0 8 16
16 8

• Average Turn around time = 9.67


• Average waiting time = 4.33

12
PROGRAM:
// C program for implementation of FCFS

#include<stdio.h>

// Function to find the waiting time for all

// processes

void findWaitingTime(int processes[], int n,

int bt[], int wt[])

// waiting time for first process is 0

wt[0] = 0;

// calculating waiting time

for (int i = 1; i < n ; i++ )

wt[i] = bt[i-1] + wt[i-1] ;

// Function to calculate turn around time

void findTurnAroundTime( int processes[], int n,

int bt[], int wt[], int tat[])

// calculating turnaround time by adding

// bt[i] + wt[i]

for (int i = 0; i < n ; i++)

tat[i] = bt[i] + wt[i];

//Function to calculate average time

void findavgTime( int processes[], int n, int bt[])

int wt[n], tat[n], total_wt = 0, total_tat = 0;

//Function to find waiting time of all processes

findWaitingTime(processes, n, bt, wt);

13
//Function to find turn around time for all processes

findTurnAroundTime(processes, n, bt, wt, tat);

//Display processes along with all details

printf("Processes Burst time Waiting time Turn around


time\n");

// Calculate total waiting time and total turn

// around time

for (int i=0; i<n; i++)

total_wt = total_wt + wt[i];

total_tat = total_tat + tat[i];

printf(" %d ",(i+1));

printf(" \t %d ", bt[i] );

printf(" \t %d",wt[i] );

printf(" \t %d\n",tat[i] );

float s=(float)total_wt / (float)n;

float t=(float)total_tat / (float)n;

printf("Average waiting time = %f",s);

printf("\n");

printf("Average turn around time = %f ",t);

// Driver code

int main()

//process id's

int processes[] = { 1, 2, 3};

int n = sizeof processes / sizeof processes[0];

14
//Burst time of all processes

int burst_time[] = {5, 3, 8};

findavgTime(processes, n, burst_time);

return 0;

15
OUTPUT:
Processes Burst time Waiting time Turn around time
1 5 0 5
2 3 5 8
3 8 8 16
Average waiting time = 4.333333
Average turn around time = 9.666667

16
3) Write a program to simulate SJF Algorithm.
Shortest Job First or SJF CPU Scheduling
Shortest Job First (SJF) or Shortest Job Next (SJN) is a
scheduling process that selects the waiting process with the
smallest execution time to execute next. This scheduling
method may or may not be preemptive. Significantly reduces
the average waiting time for other processes waiting to be
executed.

Estimation Formula

𝑇𝑛+1 = 𝛼 ⋅ 𝑡𝑛 + (1 − 𝛼) ⋅ 𝑇𝑛

Where:

• Tn+1: Predicted burst time for the next process.

• Tn: Previously predicted burst time.

• tn: Actual burst time of the previous process.

• α: Smoothing factor (0 ≤ α ≤ 1).

Characteristics of SJF Scheduling

• Shortest Job first has the advantage of having a minimum


average waiting time among all operating system
scheduling algorithms.

• It is associated with each task as a unit of time to


complete.

• It may cause starvation if shorter processes keep


coming. This problem can be solved using the concept
of ageing.

Implementation of SJF Scheduling


• Step 1: Input number of processes and their burst
times (arrival time too, if it’s non-preemptive with
arrivals).
Step 2: Sort processes by burst time (if same, use

17
arrival order).
Step 3: Start with the process having the shortest burst
time.
Step 4: Calculate Completion Time = Start Time + Burst
Time.
Step 5: Calculate Turnaround Time = Completion Time −
Arrival Time.
Step 6: Calculate Waiting Time = Turnaround Time − Burst
Time.
Step 7: Repeat until all processes are completed.
Step 8: Compute average waiting time and turnaround
time.
Step 9: Display completion, waiting, and turnaround
times for each process along with averages.
Advantages of SJF Scheduling

• SJF is better than the First come first serve(FCFS)


algorithm as it reduces the average waiting time.

• SJF is generally used for long term scheduling.

• It is suitable for the jobs running in batches, where


run times are already known.

• SJF is probably optimal in terms of average Turn Around


Time (TAT).

Disadvantages of SJF Scheduling

• SJF may cause very long turn-around times or starvation.

• In SJF job completion time must be known earlier.

• Many times it becomes complicated to predict the length


of the upcoming CPU request.

18
Example:

Consider the following table of arrival time and burst time


for three processes P1, P2 and P3.

Process Burst Time Arrival Time

P1 6 ms 0 ms

P2 8 ms 0 ms

P3 3 ms 0 ms

19
PROGRAM:

#include <stdio.h>

int main()

// Matrix for storing Process Id, Burst

// Time, Average Waiting Time & Average

// Turn Around Time.

int A[100][4];

int i, j, n, total = 0, index, temp;

float avg_wt, avg_tat;

printf("Enter number of process: ");

scanf("%d", &n);

printf("Enter Burst Time:\n");

// User Input Burst Time and alloting Process Id.

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

printf("P%d: ", i + 1);

scanf("%d", &A[i][1]);

A[i][0] = i + 1;

// Sorting process according to their Burst Time.

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

index = i;

for (j = i + 1; j < n; j++)

if (A[j][1] < A[index][1])

index = j;

temp = A[i][1];

A[i][1] = A[index][1];

A[index][1] = temp;

20
temp = A[i][0];

A[i][0] = A[index][0];

A[index][0] = temp;

A[0][2] = 0;

// Calculation of Waiting Times

for (i = 1; i < n; i++) {

A[i][2] = 0;

for (j = 0; j < i; j++)

A[i][2] += A[j][1];

total += A[i][2];

avg_wt = (float)total / n;

total = 0;

printf("P BT WT TAT\n");

// Calculation of Turn Around Time and printing the

// data.

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

A[i][3] = A[i][1] + A[i][2];

total += A[i][3];

printf("P%d %d %d %d\n", A[i][0],

A[i][1], A[i][2], A[i][3]);

avg_tat = (float)total / n;

printf("Average Waiting Time= %f", avg_wt);

printf("\nAverage Turnaround Time= %f", avg_tat);

21
OUTPUT:

Enter number of process: 3

Enter Burst Time:

P1: 6

P2: 8

P3: 3

P BT WT TAT

P3 3 0 3

P1 6 3 9

P2 8 9 17

Average Waiting Time= 4.000000

Average Turnaround Time= 9.666667

22
4) Write a program to simulate Round Robin Algorithm.

Round Robin Algorithm

Round Robin Scheduling is a method used by operating systems


to manage the execution time of multiple processes that are
competing for CPU attention. It is called "round robin"
because the system rotates through all the processes,
allocating each of them a fixed time slice or "quantum",
regardless of their priority.

The primary goal of this scheduling method is to ensure that


all processes are given an equal opportunity to execute,
promoting fairness among tasks.

• Process Arrival: Processes enter the system and are


placed in a queue.

• Time Allocation: Each process is given a certain amount


of CPU time, called a quantum.

• Execution: The process uses the CPU for the allocated


time.

• Rotation: If the process completes within the time, it


leaves the system. If not, it goes back to the end of
the queue.

• Repeat: The CPU continues to cycle through the queue


until all processes are completed.

Advantages of Round Robin Scheduling

• Fairness: Each process gets an equal share of the CPU.

• Simplicity: The algorithm is straightforward and easy to


implement.

• Responsiveness: Round Robin can handle multiple


processes without significant delays, making it ideal
for time-sharing systems.

23
Disadvantages of Round Robin Scheduling:

• Overhead: Switching between processes can lead to high


overhead, especially if the quantum is too small.

• Underutilization: If the quantum is too large, it can


cause the CPU to feel unresponsive as it waits for a
process to finish its time.

Example
Processes with Same Arrival Time
• Consider the following table of arrival time and burst
time for three processes P1, P2 and P3 and given Time
Quantum = 2 ms

Process Burst Time Arrival Time

P1 4 ms 0 ms

P2 5 ms 0 ms

P3 3 ms 0 ms

24
PROGRAM:
#include <stdio.h>

void main() {

int i, processes, sum = 0, cnt = 0, y, q, wt = 0, tat = 0, at[10],


bt[10], temp[10];

float avg_waitt, avg_turnat;

// Input the number of processes

printf("Total number of processes in the system: ");

scanf("%d", &processes);

y = processes; // Assign number of processes to y

// Input arrival time and burst time for each process

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

printf("\nEnter the Arrival and Burst time of Process[%d]\n", i


+ 1);

printf("Arrival time: ");

scanf("%d", &at[i]);

printf("Burst time: ");

scanf("%d", &bt[i]);

temp[i] = bt[i]; // Initialize remaining burst time

// Input the time quantum

printf("Enter the Time Quantum: ");

scanf("%d", &q);

// Display header for the process info

printf("\nProcess No \tBurst Time \tTAT \t\tWaiting Time\n");

// Scheduling loop

for(sum = 0, i = 0; y != 0;) {

if(temp[i] <= q && temp[i] > 0) {

25
sum = sum + temp[i];

temp[i] = 0;

cnt = 1;

} else if(temp[i] > 0) {

temp[i] = temp[i] - q;

sum = sum + q;

if(temp[i] == 0 && cnt == 1) {

y--;

printf("\nProcess No[%d] \t%d \t\t%d \t\t%d", i + 1, bt[i],


sum - at[i], sum - at[i] - bt[i]);

wt = wt + sum - at[i] - bt[i];

tat = tat + sum - at[i];

cnt = 0;

if(i == processes - 1) {

i = 0;

} else if(at[i + 1] <= sum) {

i++;

} else {

i = 0;

// Calculate average waiting time and turnaround time

avg_waitt = wt * 1.0 / processes;

avg_turnat = tat * 1.0 / processes;

printf("\n\n Average Turnaround Time: %f", avg_turnat);

printf("\nAverage Waiting Time: %f", avg_waitt);

26
OUTPUT:
Total number of processes in the system: 3

Enter the Arrival and Burst time of Process[1]


Arrival time: 0
Burst time: 4

Enter the Arrival and Burst time of Process[2]


Arrival time: 0
Burst time: 5

Enter the Arrival and Burst time of Process[3]


Arrival time: 0
Burst time: 3
Enter the Time Quantum: 2

Process No Burst Time TAT Waiting Time

Process No[1] 4 8 4
Process No[3] 3 11 8
Process No[2] 5 12 7

Average Turnaround Time: 10.333333


Average Waiting Time: 6.333333

27
5) Write a program to simulate FIFO page replacement
Algorithm.

FIFO page replacement Algorithm:


Page Replacement Algorithms are needed to decide which page
needed to be replaced when new page comes in.

Whenever a new page is referred and not present in


memory, page fault occurs and Operating System replaces one
of the existing pages with newly needed page.

Different page replacement algorithms suggest different ways


to decide which page to replace. The target for all algorithms
is to reduce number of page faults.

First In First Out (FIFO) page replacement algorithm:

This is the simplest page replacement algorithm. In this


algorithm, operating system keeps track of all pages in the
memory in a queue, oldest page is in the front of the queue.
When a page needs to be replaced page in the front of the
queue is selected for removal.

Implementation - Let capacity be the number of pages that


memory can hold. Let set be the current set of pages in
memory.

1. Start traversing the pages.


i) If set holds less pages than capacity.
a) Insert page into the set one by one until
the size of set reaches capacity or all
page requests are processed.
b) Simultaneously maintain the pages in the
queue to perform FIFO.
c) Increment page fault
ii) Else
If current page is present in set, do nothing.

28
Else
a) Remove the first page from the queue
as it was the first to be entered in
the memory
b) Replace the first page in the queue with
the current page in the string.
c) Store current page in the queue.
d) Increment page faults.

2. Return page faults.

29
PROGRAM:

#include <stdio.h>

#include <stdlib.h>

int main() {

int incomingStream[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0,


1, 7, 0, 1}; // Example page reference string

int pages = sizeof(incomingStream) / sizeof(incomingStream[0]);

int frames = 3; // Number of available page frames

int temp[frames];

int pageFaults = 0;

int m, n, s;

for (m = 0; m < frames; m++) {

temp[m] = -1;

printf("Incoming\tFrame 1\t\tFrame 2\t\tFrame 3\n");

for (m = 0; m < pages; m++) {

s = 0;

for (n = 0; n < frames; n++) {

if (incomingStream[m] == temp[n]) {

s++;

pageFaults--;

pageFaults++;

30
if ((pageFaults <= frames) && (s == 0)) {

int i = 0;

while (temp[i] != -1) {

i++;

temp[i] = incomingStream[m];

} else if (s == 0) {

temp[(pageFaults - 1) % frames] = incomingStream[m];

printf("%d\t\t", incomingStream[m]);

for (n = 0; n < frames; n++) {

if (temp[n] != -1) {

printf("%d\t\t", temp[n]);

} else {

printf("-\t\t");

printf("\n");

printf("\nTotal Page Faults:\t%d\n", pageFaults);

return 0;

31
OUTPUT:

Incoming Frame 1 Frame 2 Frame 3

7 7 - -

0 7 0 -

1 7 0 1

2 2 0 1

0 2 0 1

3 2 3 1

0 2 3 0

4 4 3 0

2 4 2 0

3 4 2 3

0 0 2 3

3 0 2 3

2 0 2 3

1 0 1 3

2 0 1 2

0 0 1 2

1 0 1 2

7 7 1 2

0 7 0 2

1 7 0 1

Total Page Faults: 15

32
6) Write a program to implement Producer Consumer using
semaphore.

Producer Consumer Solution using Semaphores

The Producer-Consumer problem is a classic example of a


synchronization problem in operating systems. It demonstrates
how processes or threads can safely share resources without
conflicts. This problem belongs to the process
synchronization domain, specifically dealing with
coordination between multiple processes sharing a common
buffer.

In this problem, we have:

• Producers: Generate data items and place them in a shared


buffer.

• Consumers: Remove and process data items from the buffer.

The main challenge is to ensure:

1. A producer does not add data to a full buffer.

2. A consumer does not remove data from an empty buffer.

3. Multiple producers and consumers do not access the buffer


simultaneously, preventing race conditions.

Semaphore: The Synchronization Tool

A semaphore is an integer-based signaling mechanism used to


coordinate access to shared resources. It supports two atomic
operations:

• wait(S): Decreases the semaphore value by 1. If the value


is ≤0, the process waits.

• signal(S): Increases the semaphore value by 1,


potentially unblocking waiting processes.

Problem Statement

33
Consider a fixed-size buffer shared between a producer and a
consumer.

• The producer generates an item and places it in the


buffer.

• The consumer removes an item from the buffer.

The buffer is the critical section. At any moment:

• A producer cannot place an item if the buffer is full.

• A consumer cannot remove an item if the buffer is empty.

To manage this, we use three semaphores:

• mutex – ensures mutual exclusion when accessing the


buffer.

• full – counts the number of filled slots in the buffer.

• empty – counts the number of empty slots in the buffer.

34
PROGRAM:

#include <stdio.h>

#include <pthread.h>

#include <stdlib.h>

#include <unistd.h>

#define BUFFER_SIZE 5

int buffer[BUFFER_SIZE];

int in = 0, out = 0, count = 0;

pthread_mutex_t mutex;

pthread_cond_t not_full;

pthread_cond_t not_empty;

// Producer function

void* producer(void* arg) {

while (1) {

int item = rand() % 100; // produce an item

pthread_mutex_lock(&mutex);

while (count == BUFFER_SIZE) // buffer full

pthread_cond_wait(&not_full, &mutex);

buffer[in] = item;

printf("Produced: %d at %d\n", item, in);

in = (in + 1) % BUFFER_SIZE;

35
count++;

pthread_cond_signal(&not_empty); // signal buffer has item

pthread_mutex_unlock(&mutex);

sleep(1); // simulate production time

return NULL;

// Consumer function

void* consumer(void* arg) {

while (1) {

pthread_mutex_lock(&mutex);

while (count == 0) // buffer empty

pthread_cond_wait(&not_empty, &mutex);

int item = buffer[out];

printf("Consumed: %d at %d\n", item, out);

out = (out + 1) % BUFFER_SIZE;

count--;

pthread_cond_signal(&not_full); // signal buffer has space

pthread_mutex_unlock(&mutex);

sleep(1); // simulate consumption time

36
return NULL;

int main() {

pthread_t prod, cons;

pthread_mutex_init(&mutex, NULL);

pthread_cond_init(&not_full, NULL);

pthread_cond_init(&not_empty, NULL);

pthread_create(&prod, NULL, producer, NULL);

pthread_create(&cons, NULL, consumer, NULL);

pthread_join(prod, NULL);

pthread_join(cons, NULL);

pthread_mutex_destroy(&mutex);

pthread_cond_destroy(&not_full);

pthread_cond_destroy(&not_empty);

return 0;

37
OUTPUT:

Produced: 83 at 0

Consumed: 83 at 0

Produced: 86 at 1

Consumed: 86 at 1

Produced: 77 at 2

Consumed: 77 at 2

Produced: 15 at 3

Consumed: 15 at 3

Produced: 93 at 4

Consumed: 93 at 4

Produced: 35 at 0

Consumed: 35 at 0

Produced: 86 at 1

Consumed: 86 at 1

Produced: 92 at 2

Consumed: 92 at 2

Produced: 49 at 3

Consumed: 49 at 3

Produced: 21 at 4

Consumed: 21 at 4

Produced: 62 at 0

Consumed: 62 at 0

And so on…

38
7) Write a program to simulate Deadlock Detection.

Deadlock Detection:

In operating systems, managing resources like memory, files,


and processors is very important. Sometimes, processes (or
programs) get stuck waiting for each other to release
resources, leading to a situation called a deadlock. To handle
deadlocks, operating systems use special methods called
deadlock detection algorithms. These algorithms help identify
when a deadlock has happened so that the system can fix the
problem. This is different from methods that try to prevent
deadlocks from happening at all, which can be more
restrictive.

Deadlock Detection Algorithm:

A deadlock detection algorithm is a technique used by an


operating system to identify deadlocks in the system. This
algorithm checks the status of processes and resources to
determine whether any deadlock has occurred and takes
appropriate actions to recover from the deadlock.

Deadlock detection algorithms work by regularly checking the


current state of resource usage in the system. They often use
a visual tool called a resource allocation graph. This graph
shows which processes are using which resources and which
resources each process is waiting for. By looking for cycles
in this graph, the algorithm can spot deadlocks.

Deadlock detection algorithms are vital in operating systems


to prevent processes from getting stuck in a circular wait.

The algorithm employs several times varying data


structures:

• Available: A vector of length m indicates the number of


available resources of each type.

39
• Allocation: An n*m matrix defines the number of
resources of each type currently allocated to a process.
The column represents resource and rows represent a
process.

• Request: An n*m matrix indicates the current request of


each process. If request[i][j] equals k then process
P i is requesting k more instances of resource type R j .

Advantages of Deadlock Detection Algorithms

• Improved System Stability: Deadlocks are a major concern


in operating systems , and detecting and resolving
deadlocks can help to improve the stability of the
system.

• Better Resource Utilization: By detecting deadlocks and


freeing resources, the operating system can ensure that
resources are efficiently utilized and that the system
remains responsive to user requests.

• Easy Implementation: Some deadlock detection algorithms,


such as the Wait-For Graph , are relatively simple to
implement and can be used in a wide range of operating
systems and systems with different resource allocation
and synchronization requirements.

Disadvantages of Deadlock Detection Algorithms

• Performance Overhead: Deadlock detection algorithms can


introduce a significant overhead in terms of
performance, as the system must regularly check for
deadlocks and take appropriate action.

• Complexity: Some deadlock detection algorithms, such as


the Resource Allocation Graph or Timestamping, are more
complex to implement and require a deeper understanding
of the system and its behavior.

40
• False Positives and Negatives: Deadlock detection
algorithms are not perfect and may produce false
positives or negatives, indicating the presence of
deadlocks when they do not exist or failing to detect
deadlocks that do exist.

• Overall, the choice of deadlock detection algorithm


depends on the specific requirements of the system, the
trade-offs between performance, complexity, and
accuracy, and the risk tolerance of the system. The
operating system must balance these factors to ensure
that deadlocks are detected and resolved effectively and
efficiently.

41
PROGRAM:

#include <stdio.h>

int main() {

int n, m, i, j, k;

printf("Enter number of processes: ");

scanf("%d", &n); // Number of processes (P1, P2, ...)

printf("Enter number of resources: ");

scanf("%d", &m); // Number of resource types (R1, R2, ...)

int alloc[10][10], request[10][10], avail[10], work[10], finish[10];

// Input Allocation Matrix

printf("Enter Allocation Matrix (%dx%d):\n", n, m);

for (i = 0; i < n; i++)

for (j = 0; j < m; j++)

scanf("%d", &alloc[i][j]);

// Input Request Matrix

printf("Enter Request Matrix (%dx%d):\n", n, m);

for (i = 0; i < n; i++)

for (j = 0; j < m; j++)

scanf("%d", &request[i][j]);

// Input Available Resources

printf("Enter Available Resources (%d elements):\n", m);

for (i = 0; i < m; i++)

scanf("%d", &avail[i]);

42
// Initialize Work and Finish vectors

for (i = 0; i < m; i++)

work[i] = avail[i];

for (i = 0; i < n; i++)

finish[i] = 0; // 0 means false

int deadlock = 0;

int can_execute = 1;

while (can_execute) {

can_execute = 0;

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

if (finish[i] == 0) {

int possible = 1;

for (j = 0; j < m; j++) {

if (request[i][j] > work[j]) {

possible = 0;

break;

if (possible) {

for (k = 0; k < m; k++)

work[k] += alloc[i][k];

finish[i] = 1;

can_execute = 1;

43
}

// Check for deadlock (any process still not finished)

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

if (finish[i] == 0) {

deadlock = 1;

break;

if (deadlock) {

printf("\nSystem is in a DEADLOCKED state. Deadlocked processes:


");

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

if (finish[i] == 0) {

printf("P%d ", i);

printf("\n");

} else {

printf("\nSystem is NOT in a deadlocked state.\n");

return 0;

44
OUTPUT:

Enter number of processes: 3

Enter number of resources: 5

Enter Allocation Matrix (3x5):

0 1 0

2 0 0

3 0 3

2 1 1

0 0 2

Enter Request Matrix (3x5):

0 0 0

2 0 2

0 0 0

1 0 0

0 0 2

Enter Available Resources (5 elements):

2 0 2 1 0

System is in a DEADLOCKED state. Deadlocked processes: P0 P1


P2

45
8) Write a program to implement Paging Memory Management.

Paging:

Paging is the process of moving parts of a program, called


pages, from secondary storage into the main memory (RAM). The
main idea behind paging is to break a program into smaller
fixed-size blocks called pages.

• Process does not have to be allocated in a contiguous


memory space.

• The whole process does not have to be in main memory,


some pages can be present, and some pages can be loaded
when needed. It allows more processes and even processes
larger than main memory to run.

• Memory allocation is simplified as memory is always


allocated in fixed sized pages.

Paging in Memory Management

Paging addresses common challenges in allocating and managing


memory efficiently. Why paging is needed as a Memory
Management technique:

• Memory isn’t always available in a single


block: Programs often need more memory than what is
available in a single continuous block. Paging breaks
memory into smaller, fixed-size pieces, making it easier
to allocate scattered free spaces.

• Processes size can increase or decrease programs don’t


need to occupy continuous memory, so they can grow
dynamically without the need to be moved.

Important Features of Paging

• Logical to physical address mapping: Paging divides a


process's logical address space into fixed-size pages.

46
Each page maps to a frame in physical memory, enabling
flexible memory management.

• Fixed page and frame size: Pages and frames have the
same fixed size. This simplifies memory management and
improves system performance.

• Page table entries: Each logical page is represented by


a page table entry (PTE). A PTE stores the corresponding
frame number and control bits.

• Number of page table entries: The page table has one


entry per logical page. Thus, its size equals the number
of pages in the process's address space.

• Page table stored in main memory: The page table is kept


in main memory. This can add overhead when processes are
swapped in or out.

Steps Involved in Paging:

• Step 1 Divide Memory: Logical -> Pages, Physical ->


Frames.

• Step 2 Allocate Pages: Load pages into available


frames.

• Step 3 Page Table: Map logical pages to physical


frames.

• Step 4 Translate Address: Convert logical to physical


address.

• Step 5 Handle Page Fault: Load missing pages from disk.

• Step 6 Run Program: CPU uses page table during


execution.

47
PROGRAM:

#include<stdio.h>

#define MAX 50

int main()

int page[MAX],i,n,f,ps,off,pno;

int choice=0;

printf("\nEnter the no of peges in memory: ");

scanf("%d",&n);

printf("\nEnter page size: ");

scanf("%d",&ps);

printf("\nEnter no of frames: ");

scanf("%d",&f);

for(i=0;i<n;i++)

page[i]=-1;

printf("\nEnter the page table\n");

printf("(Enter frame no as -1 if that page is not present in


any frame)\n\n");

printf("\npageno\tframeno\n-------\t-------");

for(i=0;i<n;i++)

printf("\n\n%d\t\t",i);

scanf("%d",&page[i]);

do

48
{

printf("\n\nEnter the logical address(i.e,page no &


offset):");

scanf("%d%d",&pno,&off);

if(page[pno]==-1)

printf("\n\nThe required page is not available in any of


frames");

else

printf("\n\nPhysical address(i.e,frame no &


offset):%d,%d",page[pno],off);

printf("\nDo you want to continue(1/0)?:");

scanf("%d",&choice);

}while(choice==1);

return 1;

49
OUTPUT:

Enter the no of peges in memory: 3

Enter page size: 5

Enter no of frames: 2

Enter the page table


(Enter frame no as -1 if that page is not present in any
frame)

pageno frameno
------- -------
0 -1

1 2

2 0

Enter the logical address(i.e,page no & offset):12 54

Physical address(i.e,frame no & offset):0,54


Do you want to continue(1/0)?:1

Enter the logical address(i.e,page no & offset):1 4

Physical address(i.e,frame no & offset):2,4


Do you want to continue(1/0)?:0

50
9) Write a program to implement File Allocation Technique.

File Allocation Methods

File allocation methods refer to the strategies employed by


computer operating systems for the efficient distribution of
storage space on disks or other storage media. Their main
objective is to optimize the utilization of available space
and minimize fragmentation, which can impede file access and
decrease the overall performance of the system. There are
several different file allocation methods that are commonly
used, each with its own strengths and weaknesses.

Contiguous File Allocation

In this method, files are stored in a continuous block of


free space on the disk meaning that all the data for a
particular file is stored in one continuous section of the
disk. When a file is created, the operating system searches
for a contiguous block of free space large enough to
accommodate the file. If such a block is found, the file is
stored in that block, and the operating system keeps track
of the starting address and the size of the block.

The advantage of contiguous file allocation is that it


provides fast access to files, as the operating system only
needs to remember the starting address of the file. When a
user requests access to a file, the operating system can
quickly locate the file's starting address and read the
entire file sequentially. This method is particularly useful
for large files, such as video or audio files, which can be
accessed more quickly when stored in contiguous blocks.

However, contiguous file allocation has some limitations.


One significant disadvantage is that it can lead to
fragmentation when files are deleted or when new files are
created. If a file is deleted, the space it occupied becomes
free, but that space may not be contiguous with the

51
remaining free space on the disk. This can result in gaps or
fragments of free space scattered throughout the disk,
making it difficult for the operating system to find
contiguous blocks of free space for new files.

Linked File Allocation

In this method, files are stored in non-contiguous blocks of


free space on the disk, and each block is linked to the next
block using a pointer. When a file is created, the operating
system searches for a series of free blocks that are large
enough to store the file, and it links them together using
pointers. Each block contains the address of the next block
in the file, allowing the operating system to access the
entire file by following the chain of pointers.

The advantage of linked file allocation is that it can


accommodate files of any size, as the file can be stored in
multiple non-contiguous blocks. This method also avoids
fragmentation, as files can be stored in any available free
space on the disk, without the need to find a contiguous
block of free space.

However, linked file allocation has some limitations. One


significant disadvantage is that it can result in slower
access times to files, as the operating system needs to
follow the chain of pointers to access the entire file. This
method may also require more disk space, as each block
contains a pointer to the next block in the file.
Additionally, if a pointer becomes damaged or lost, it can
result in the loss of the entire file, as the operating
system cannot access the entire chain of blocks.

Indexed File Allocation

To address some of the limitations, operating systems can


use a variation of linked file allocation called indexed
file allocation. In indexed file allocation, files are

52
stored in noncontiguous blocks, but instead of linking each
block together, the operating system creates an index block
that contains a list of pointers to each block in the file.
When a file is created, the operating system searches for a
series of free blocks that are large enough to store the
file and creates an index block that contains pointers to
each of those blocks. Each block of the file is then stored
in a separate block on the disk.

The advantage of indexed file allocation is that it provides


fast access to files, as the operating system only needs to
read the index block to locate the file's blocks. This
method also avoids fragmentation, as files can be stored in
any available free space on the disk, without the need to
find a contiguous block of free space. Indexed file
allocation also reduces the risk of data loss, as the index
block can be duplicated to provide redundancy.

However, indexed file allocation has some limitations. One


significant disadvantage is that it can result in wasted
disk space, as the index block can take up a significant
amount of space on the disk. This method also requires more
disk space than linked file allocation, as each block of the
file is stored separately on the disk.

53
PROGRAM:

#include<stdio.h>

#include<stdlib.h> // Required for exit()

// Define a structure to hold file information for the


simulation

struct file {

char fname[10];

int start, size, block[10];

};

void main() {

int i, j, n;

struct file f[10];

printf("Enter no. of files: ");

scanf("%d", &n);

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

printf("\nEnter file name: ");

scanf("%s", &f[i].fname);

printf("Enter starting block: ");

scanf("%d", &f[i].start);

f[i].block[0] = f[i].start; // Store the start block


as the first element

54
printf("Enter no. of blocks: ");

scanf("%d", &f[i].size);

printf("Enter block numbers (sequentially as they


would be linked): ");

// Read the subsequent linked block numbers

for (j = 1; j <= f[i].size - 1; j++) {

scanf("%d", &f[i].block[j]);

printf("\nFile\tStart\tSize\tBlock Sequence\n");

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

printf("%s\t%d\t%d\t", f[i].fname, f[i].start,


f[i].size);

// Print the linked sequence of blocks

for (j = 0; j <= f[i].size - 2; j++) {

printf("%d--->", f[i].block[j]);

printf("%d", f[i].block[j]); // Print the last block


without the arrow

printf("\n");

55
OUTPUT:

Enter no. of files: 2

Enter file name: Devasish

Enter starting block: 3

Enter no. of blocks: 1

Enter block numbers (sequentially as they would be linked):

Enter file name: Anusha

Enter starting block: 5

Enter no. of blocks: 2

Enter block numbers (sequentially as they would be linked):

File Start Size Block Sequence

Devasish 3 1 3

Anusha 5 2 5--->1

56
10) UNIX COMMANDS?

Unix commands are a set of commands that are used to interact


with the Unix operating system. Unix is a powerful, multi-
user, multi-tasking operating system that was developed in
the 1960s by Bell Labs. Unix commands are entered at the
command prompt in a terminal window, and they allow users to
perform a wide variety of tasks, such as managing files and
directories, running processes, managing user accounts, and
configuring network settings. Unix is now one of the most
commonly used Operating systems used for various purposes
such as Personal use, Servers, Smartphones, and many more. It
was developed in the 1970's at AT& T Labs by two famous
personalities Dennis M. Ritchie and Ken Thompson.

• You'll be surprised to know that the most popular


programming language C came into existence to write the
Unix Operating System.

• Linux is Unix-Like operating system.

• The most important part of the Linux is Linux


Kernel which was first released in the early 90s by Linus
Torvalds. There are several Linux distros available
(most are open-source and free to download and use) such
as Ubuntu, Debian, Fedora, Kali, Mint, Gentoo, Arch and
much more.

• Now coming to the Basic and most usable commands of


Linux/Unix part. (Please note that all the linux/unix
commands are run in the terminal of a linux
[Link] is like command prompt as that of in
Windows OS)

• Linux/Unix commands are case-sensitive i.e Hello is


different from hello.

57
File System Navigation Unix Command

Command Description Example

cd Changes the current working directory. cd Documents

Lists files and directories in the


ls
ls current directory.

Prints the current working directory. pwd


pwd

mkdir
Creates a new directory.
mkdir new_folder

rmdir
Removes an empty directory.
rmdir empty_folder

mv [Link]
Moves files or directories.
mv Documents/

58
File Manipulation Unix Command

Command Description Example

Creates an empty file or updates touch


touch the access and modification times. new_file.txt

cp [Link]
Copies files or directories.
cp [Link]

mv [Link]
Moves files or directories.
mv Documents

rm Remove files or directories. rm old_file.txt

Changes the permissions of a file


chmod 644 [Link]
chmod or directory.

Changes the owner and group of a chown user:group


chown file or directory. [Link]

ln -s target_file
Creates links between files.
ln symlink

Concatenates files and displays cat [Link]


cat their contents. [Link]

Displays the first few lines of a


head [Link]
head file.

59
Command Description Example

Displays the last few lines of a


tail [Link]
tail file.

Displays the contents of a file


more [Link]
more page by page.

Displays the contents of a file


less [Link]
less with advanced navigation features.

diff [Link]
Compares files line by line.
diff [Link]

Applies a diff file to update a patch [Link] <


patch target file. [Link]

60
Process Management Unix Command

Command Description Example

Displays information about active


processes, including their status and ps aux
ps IDs.

Displays a dynamic real-time view of


system processes and their resource top
top usage.

Terminates processes using their process


kill <pid>
kill IDs (PIDs).

Sends signals to processes based on name pkill -9


pkill or other attributes. firefox

killall -9
Terminates processes by name.
killall firefox

Changes the priority of running renice -n


renice processes. 10 <pid>

Runs a command with modified scheduling nice -n 10


nice priority. command

pstree Displays running processes as a tree. pstree

61
Command Description Example

Searches for processes by name or other pgrep


pgrep attributes. firefox

Lists active jobs and their status in


jobs
jobs the current shell session.

bg Puts a job in the background. bg <job_id>

Brings a background job to the


fg <job_id>
fg foreground.

Runs a command immune to hangups, with nohup


nohup output to a specified file. command &

Removes jobs from the shell's job table, disown


disown allowing them to run independently. <job_id>

62
Text Processing Unix Command

Command Description Example

Searches for patterns


grep "error" [Link]
grep in text files.

Processes and sed


transforms text 's/old_string/new_string/g'
sed streams. [Link]

Processes and analyzes


text files using a
awk '{print $1, $3}' [Link]
pattern scanning and
awk processing language.

Network Communication Unix Command

Command Description Example

Tests connectivity
with another host
ping [Link]
using ICMP echo
ping requests.

Traces the route


that packets take to traceroute [Link]
traceroute reach a destination.

63
Command Description Example

Queries DNS servers


for domain name
nslookup [Link]
resolution and IP
nslookup address information.

Performs DNS
queries, providing
dig [Link]
detailed information
dig about DNS records.

Performs DNS
lookups, displaying
host [Link]
domain name to IP
host address resolution.

Retrieves
information about
whois [Link]
domain registration
whois and ownership.

Provides secure
remote access to a ssh username@hostname
ssh system.

Securely copies
scp [Link]
files between hosts
username@hostname:/path/
scp over a network.

64
Command Description Example

Transfers files
between hosts using
ftp hostname
the File Transfer
ftp Protocol (FTP).

Establishes
interactive text-
telnet hostname
based communication
telnet with a remote host.

Displays network
connections, routing
tables, interface
statistics,
netstat -tuln
masquerade
connections, and
multicast
netstat memberships.

Displays or
configures network
ifconfig
interfaces and their
ifconfig settings.

Configures wireless
iwconfig wlan0
iwconfig network interfaces.

65
Command Description Example

Displays or modifies
the IP routing route -n
route table.

Displays or modifies
the Address
arp -a
Resolution Protocol
arp (ARP) cache.

Displays socket
ss -tuln
ss statistics.

Displays or sets the


hostname
hostname system's hostname.

Combines the
functionality of
ping and traceroute,
mtr [Link]
providing detailed
network diagnostic
mtr information.

66
System Administration Unix Command

Command Description Example

df Displays disk space usage. df -h

Displays disk usage of files du -sh


du and directories. /path/to/directory

Manages cron jobs, which are


scheduled tasks that run at crontab -e
crontab -e predefined times or intervals.

Text Editors in Unix

Text Editor Description Example

Vi (Vim) is a highly
configurable, powerful,
Open a file with Vim: vim
and feature-rich text
filename
editor based on the
Exit Vim editor: Press Esc,
original Vi editor. Vim
then type :wq and
offers modes for both
press Enter
command-line operations
Vi / Vim and text editing.

Emacs is a versatile text Open a file with


editor with extensive Emacs: emacs filename
customization Save and exit Emacs:
Emacs
capabilities and support Press Ctrl + X, then Ctrl +

67
Text Editor Description Example

for various programming S and Ctrl + X, then Ctrl +


languages. C to exit

Open a file with Nano: nano


Nano is a simple and user-
filename
friendly text editor
Save and exit Nano:
designed for ease of use
Press Ctrl + O, then Ctrl +
and accessibility.
Nano X

Ed is a standard Unix text


editor that operates in Open a file with Ed: ed
line-oriented mode, filename
making it suitable for Exit Ed editor: Type q and
batch processing and press Enter
Ed automation tasks.

Jed is a lightweight yet


Open a file with Jed: jed
powerful text editor that
filename
provides an intuitive
Save and exit Jed: Press Alt
interface and support for
+ X, then type exit and
various programming
press Enter
Jed languages.

68

You might also like