5.
Control the number of ports opened by the operating system with
a)
Semaphore b) Monitors.
a)
Using Semaphore
- Suppose
only 2 ports are available.
- If more than 2
students request, others must wait.
Program:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
sem_t port; // Semaphore variable
void* openPort(void* arg)
{
int id = *(int*)arg;
sem_wait(&port); // Request
a port
printf("Student %d is using a port\n", id);
sleep(2); // Using port
printf("Student %d released the port\n", id);
sem_post(&port); // Release
port
return NULL;
}
int main()
{
pthread_t t1, t2, t3;
int id1 = 1, id2 = 2, id3 = 3;
sem_init(&port, 0, 2); //
Only 2 ports available
pthread_create(&t1, NULL, openPort, &id1);
pthread_create(&t2, NULL, openPort, &id2);
pthread_create(&t3, NULL, openPort, &id3);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
sem_destroy(&port);
return 0;
}
OUTPUT:
Student 1 is using a port
Student 2 is using a port
Student 1 released the port
Student 2 released the port
Student 3 is using a port
Student 3 released the port
b)Monitor
Concept in C
Suppose
only 2 ports are available.
Program:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_PORTS 2
int available_ports = MAX_PORTS;
pthread_mutex_t mutex;
pthread_cond_t condition;
void* use_port(void* arg)
{
int id = *(int*)arg;
pthread_mutex_lock(&mutex);
// Enter monitor
while (available_ports == 0)
{
printf("Student %d waiting for
port...\n", id);
pthread_cond_wait(&condition,
&mutex);
}
available_ports--;
printf("Student %d opened a port\n", id);
pthread_mutex_unlock(&mutex);
// Exit monitor
sleep(2); // Using port
pthread_mutex_lock(&mutex);
available_ports++;
printf("Student %d closed the port\n", id);
pthread_cond_signal(&condition);
// Wake one waiting thread
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t t1, t2, t3;
int id1 = 1, id2 = 2, id3 = 3;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&condition, NULL);
pthread_create(&t1, NULL, use_port, &id1);
pthread_create(&t2, NULL, use_port, &id2);
pthread_create(&t3, NULL, use_port, &id3);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&condition);
return 0;
}
OUTPUT:
Student 1 opened a port
Student 3 opened a port
Student 2 waiting for port...
Student 1 closed the port
Student 3 closed the port
Student 2 opened a port
Student 2 closed the port
6. Write a program to illustrate
concurrent execution of threads using pthreads library.
Threads
Using Pthreads Library
What
is a Thread?
A thread
is the smallest unit of execution inside a process.
A process can contain multiple threads that run concurrently.
Threads
share:
- Same memory
- Same global
variables
- Same resources of
the process
But each
thread has:
- Its own stack
- Its own program
counter
- Its own registers
What
is Pthreads?
Pthreads
(POSIX Threads)
is a standard C library used for creating and managing threads in Unix/Linux
systems.
It
allows:
- Creating threads
- Synchronizing
threads
- Controlling
execution of threads
Header
file used:
#include
<pthread.h>
Important
Pthread Functions
|
Function |
Purpose |
|
pthread_create() |
Creates
a new thread |
|
pthread_exit() |
Terminates
a thread |
|
pthread_join() |
Waits
for a thread to finish |
|
pthread_mutex_lock() |
Locks a
mutex |
|
pthread_mutex_unlock() |
Unlocks
a mutex |
Syntax
of Creating a Thread
pthread_create(&thread_id,
NULL, function_name, argument);
- thread_id → Thread
variable
- function_name →
Function executed by thread
- argument → Data
passed to thread
Life
Cycle of a Thread
- Thread Creation
- Thread Execution
- Thread Termination
Advantages of Threads
·
Faster
execution
·
Better
CPU utilization
·
Resource
sharing
·
Efficient
communication
Example Structure:
#include <stdio.h>
#include <pthread.h>
void* myThread(void* arg)
{
printf("Thread is running\n");
return NULL;
}
int main()
{
pthread_t t;
pthread_create(&t, NULL, myThread, NULL);
pthread_join(t, NULL);
return 0;
}
OUTPUT:
Thread is running
Program:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// Function executed by Thread 1
void* task1(void* arg)
{
for(int i = 1; i <= 5; i++)
{
printf("Thread 1: %d\n", i);
sleep(1); // Delay to show concurrency
}
return NULL;
}
// Function executed by Thread 2
void* task2(void* arg)
{
for(int i = 1; i <= 5; i++)
{
printf("Thread 2: %d\n", i);
sleep(1);
}
return NULL;
}
int main()
{
pthread_t t1, t2;
// Create threads
pthread_create(&t1, NULL, task1, NULL);
pthread_create(&t2, NULL, task2, NULL);
// Wait for threads to finish
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Both threads finished execution.\n");
return 0;
}
OUTPUT:
Thread 1: 1
Thread 2: 1
Thread 1: 2
Thread 2: 2
Thread 1: 3
Thread 2: 3
Thread 1: 4
Thread 2: 4
Thread 1: 5
Thread 2: 5
Both threads finished execution.
7. Write a program to solve
producer-consumer problem using Semaphores.
Program:
👉 Buffer size = 3
👉
Produce & consume only 5 items
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define SIZE 3
int buffer[SIZE];
int in = 0, out = 0;
sem_t empty, full;
pthread_mutex_t mutex;
// Producer
void* producer(void* arg)
{
for(int i = 1; i <= 5; i++)
{
sem_wait(&empty); // Check empty space
pthread_mutex_lock(&mutex); // Lock buffer
buffer[in] = i;
printf("Produced: %d\n", i);
in = (in + 1) % SIZE;
pthread_mutex_unlock(&mutex); // Unlock buffer
sem_post(&full); // Increase full count
sleep(1);
}
return NULL;
}
// Consumer
void* consumer(void* arg)
{
for(int i = 1; i <= 5; i++)
{
sem_wait(&full); // Check if item exists
pthread_mutex_lock(&mutex); // Lock buffer
int item = buffer[out];
printf("Consumed: %d\n",
item);
out = (out + 1) % SIZE;
pthread_mutex_unlock(&mutex); // Unlock buffer
sem_post(&empty); // Increase empty count
sleep(2);
}
return NULL;
}
int main()
{
pthread_t p, c;
sem_init(&empty, 0, SIZE); //
All slots empty
sem_init(&full, 0, 0); //
No items initially
pthread_mutex_init(&mutex, NULL);
pthread_create(&p, NULL, producer, NULL);
pthread_create(&c, NULL, consumer, NULL);
pthread_join(p, NULL);
pthread_join(c, NULL);
return 0;
}
OUTPUT:
Produced: 1
Consumed: 1
Produced: 2
Consumed: 2
Produced: 3
Produced: 4
Consumed: 3
Produced: 5
Consumed: 4
Consumed: 5
8. Implement the following memory
allocation methods for fixed partition First fit b) Worst fit c) Best fit
Memory
Allocation Methods (Fixed Partition)
In fixed
partition memory management:
- Memory is divided
into fixed size blocks.
- Processes request
memory.
- OS allocates
blocks using different strategies.
Given in
programs:
Memory
Blocks:
Block1 =
100
Block2 =
500
Block3 =
200
Block4 =
300
Block5 =
600
Processes:
P1 = 212
P2 = 417
P3 = 112
P4 = 426
First
Fit – Explanation
Rule:
Allocate
the first block that is large enough.
Step-by-Step
Execution:
➤
P1 = 212
- Block1 (100) ❌
- Block2 (500) ✅ Allocate
- Remaining Block2 =
500 − 212 = 288
➤
P2 = 417
- Block1 (100) ❌
- Block2 (288) ❌
- Block3 (200) ❌
- Block4 (300) ❌
- Block5 (600) ✅ Allocate
- Remaining Block5 =
600 − 417 = 183
➤
P3 = 112
- Block1 (100) ❌
- Block2 (288) ✅ Allocate
- Remaining Block2 =
288 − 112 = 176
➤
P4 = 426
- No block large
enough ❌ Not Allocated
First
Fit Result:
|
Process |
Block |
|
P1 |
Block2 |
|
P2 |
Block5 |
|
P3 |
Block2 |
|
P4 |
Not
Allocated |
Best
Fit – Explanation
Rule:
Allocate
the smallest block that fits.
➤
P1 = 212
Suitable
blocks:
- 500
- 300
- 600
Smallest
= 300 → Allocate
Remaining Block4 = 300 − 212 = 88
➤
P2 = 417
Suitable
blocks:
- 500
- 600
Smallest
= 500 → Allocate
Remaining Block2 = 83
➤
P3 = 112
Suitable
blocks:
- 200
- 600
Smallest
= 200 → Allocate
Remaining Block3 = 88
➤
P4 = 426
Suitable
block:
- 600 → Allocate
Remaining Block5 = 174
Best Fit Result:
|
Process |
Block |
|
P1 |
Block4 |
|
P2 |
Block2 |
|
P3 |
Block3 |
|
P4 |
Block5 |
Worst
Fit – Explanation
Rule:
Allocate
the largest available block.
➤
P1 = 212
Largest
block = 600 → Allocate
Remaining = 388
➤
P2 = 417
Largest
block = 500 → Allocate
Remaining = 83
➤
P3 = 112
Largest
block = 388 → Allocate
Remaining = 276
➤
P4 = 426
No block
large enough ❌ Not Allocated
Worst Fit Result:
|
Process |
Block |
|
P1 |
Block5 |
|
P2 |
Block2 |
|
P3 |
Block5 |
|
P4 |
Not
Allocated |
Comparison
|
Method |
Advantage |
Disadvantage |
|
First
Fit |
Fast |
More
fragmentation |
|
Best
Fit |
Less
wasted space |
Slower |
|
Worst
Fit |
Avoids
small fragments |
May
waste large blocks |
a)Program for First Fit:
#include <stdio.h>
int main()
{
int blocks[5] = {100, 500, 200, 300, 600};
int process[4] = {212, 417, 112, 426};
int i, j;
printf("First Fit Allocation:\n");
for(i = 0; i < 4; i++)
{
for(j = 0; j < 5; j++)
{
if(blocks[j] >= process[i])
{
printf("Process %d
allocated to Block %d\n", i+1, j+1);
blocks[j] -= process[i];
break;
}
}
if(j == 5)
printf("Process %d not
allocated\n", i+1);
}
return 0;
}
OUTPUT:
First Fit Allocation:
Process 1 allocated to Block 2
Process 2 allocated to Block 5
Process 3 allocated to Block 2
Process 4 not allocated
b)Program for Best Fit:
#include <stdio.h>
int main()
{
int blocks[5] = {100, 500, 200, 300, 600};
int process[4] = {212, 417, 112, 426};
int i, j, best;
printf("Best Fit Allocation:\n");
for(i = 0; i < 4; i++)
{
best = -1;
for(j = 0; j < 5; j++)
{
if(blocks[j] >= process[i])
{
if(best == -1 || blocks[j] <
blocks[best])
best = j;
}
}
if(best != -1)
{
printf("Process %d allocated
to Block %d\n", i+1, best+1);
blocks[best] -= process[i];
}
else
printf("Process %d not
allocated\n", i+1);
}
return 0;
}
OUTPUT:
Best Fit Allocation:
Process 1 allocated to Block 4
Process 2 allocated to Block 2
Process 3 allocated to Block 3
Process 4 allocated to Block 5
c)Program for Worst Fit:
#include <stdio.h>
int main()
{
int blocks[5] = {100, 500, 200, 300, 600};
int process[4] = {212, 417, 112, 426};
int i, j, worst;
printf("Worst Fit Allocation:\n");
for(i = 0; i < 4; i++)
{
worst = -1;
for(j = 0; j < 5; j++)
{
if(blocks[j] >= process[i])
{
if(worst == -1 || blocks[j]
> blocks[worst])
worst = j;
}
}
if(worst != -1)
{
printf("Process %d allocated
to Block %d\n", i+1, worst+1);
blocks[worst] -= process[i];
}
else
printf("Process %d not
allocated\n", i+1);
}
return 0;
}
OUTPUT:
Worst Fit Allocation:
Process 1 allocated to Block 5
Process 2 allocated to Block 2
Process 3 allocated to Block 5
Process 4 not allocated
9. Simulate the following page
replacement algorithms FIFO b) LRU c) LFU
Explanation:
Reference
string:
1 2 3 4 1 2 5 1 2 3 4 5
a)FIFO
(First In First Out)
Idea:
- Oldest page is
removed first.
- Like a queue.
#include <stdio.h>
int main()
{
int pages[] = {1,2,3,4,1,2,5,1,2,3,4,5};
int frames[3];
int i, j, k = 0, flag, faults = 0;
for(i = 0; i < 3; i++)
frames[i] = -1;
for(i = 0; i < 12; i++)
{
flag = 0;
for(j = 0; j < 3; j++)
{
if(frames[j] == pages[i])
{
flag = 1;
break;
}
}
if(flag == 0)
{
frames[k] = pages[i];
k = (k + 1) % 3;
faults++;
}
}
printf("Total Page Faults (FIFO) = %d", faults);
return 0;
}
OUTPUT:
Total Page Faults (FIFO) = 9
Rule:
Remove
the page that entered first (oldest).
|
Page |
Frames |
Fault? |
|
1 |
1
- - |
Yes |
|
2 |
1 2 - |
Yes |
|
3 |
1
2 3 |
Yes |
|
4 |
4 2 3 |
Yes (1
removed) |
|
1 |
4
1 3 |
Yes
(2 removed) |
|
2 |
4 1 2 |
Yes (3
removed) |
|
5 |
5
1 2 |
Yes
(4 removed) |
|
1 |
5 1 2 |
No |
|
2 |
5
1 2 |
No |
|
3 |
5 3 2 |
Yes (1
removed) |
|
4 |
5
3 4 |
Yes
(2 removed) |
|
5 |
5 3 4 |
No |
Total
Page Faults = 9
👉 FIFO keeps replacing oldest page, even if it
is frequently used
b)LRU
(Least Recently Used)
Idea:
- Remove the page
that was not used for the longest time.
#include <stdio.h>
int main()
{
int pages[] = {1,2,3,4,1,2,5,1,2,3,4,5};
int frames[3], time[3];
int i, j, faults = 0, counter = 0, pos, min;
for(i = 0; i < 3; i++)
frames[i] = -1;
for(i = 0; i < 12; i++)
{
int flag = 0;
for(j = 0; j < 3; j++)
{
if(frames[j] == pages[i])
{
counter++;
time[j] = counter;
flag = 1;
break;
}
}
if(flag == 0)
{
min = 0;
for(j = 1; j < 3; j++)
if(time[j] < time[min])
min = j;
frames[min] = pages[i];
counter++;
time[min] = counter;
faults++;
}
}
printf("Total Page Faults (LRU) = %d", faults);
return 0;
}
OUTPUT:
Total Page Faults (LRU) = 8
Rule:
Remove
the page that was least recently used.
|
Page |
Frames |
Fault? |
|
1 |
1
- - |
Yes |
|
2 |
1 2 - |
Yes |
|
3 |
1
2 3 |
Yes |
|
4 |
4 2 3 |
Yes (1
removed) |
|
1 |
4
1 3 |
Yes
(2 removed) |
|
2 |
4 1 2 |
Yes (3
removed) |
|
5 |
5
1 2 |
Yes
(4 removed) |
|
1 |
5 1 2 |
No |
|
2 |
5
1 2 |
No |
|
3 |
3 1 2 |
Yes (5
removed) |
|
4 |
3
4 2 |
Yes
(1 removed) |
|
5 |
3 4 5 |
Yes (2
removed) |
Total
Page Faults = 8
👉 LRU performs better because it removes pages
that are not used recently.
c)LFU
(Least Frequently Used)
Idea:
- Remove the page
with lowest frequency count.
#include <stdio.h>
int main()
{
int pages[] = {1,2,3,4,1,2,5,1,2,3,4,5};
int frames[3], freq[3];
int i, j, faults = 0, pos;
for(i = 0; i < 3; i++)
{
frames[i] = -1;
freq[i] = 0;
}
for(i = 0; i < 12; i++)
{
int flag = 0;
for(j = 0; j < 3; j++)
{
if(frames[j] == pages[i])
{
freq[j]++;
flag = 1;
break;
}
}
if(flag == 0)
{
pos = 0;
for(j = 1; j < 3; j++)
if(freq[j] < freq[pos])
pos = j;
frames[pos] = pages[i];
freq[pos] = 1;
faults++;
}
}
printf("Total Page Faults (LFU) = %d", faults);
return 0;
}
OUTPUT:
Total Page Faults (LFU) = 9
Rule:
Remove the page that was least recently used.
|
Page |
Frames |
Fault? |
|
1 |
1
- - |
Yes |
|
2 |
1 2 - |
Yes |
|
3 |
1
2 3 |
Yes |
|
4 |
4 2 3 |
Yes (1
removed) |
|
1 |
4
1 3 |
Yes
(2 removed) |
|
2 |
4 1 2 |
Yes (3
removed) |
|
5 |
5
1 2 |
Yes
(4 removed) |
|
1 |
5 1 2 |
No |
|
2 |
5
1 2 |
No |
|
3 |
3 1 2 |
Yes (5
removed) |
|
4 |
3
4 2 |
Yes
(1 removed) |
|
5 |
3 4 5 |
Yes (2
removed) |
Total
Page Faults = 8
👉 LRU performs better because it removes pages
that are not used recently.
10. Simulate Paging Technique of
memory management.
Concept
of Paging
What
is paging?
Paging is
a memory management technique in which:
- Physical memory is
divided into fixed size blocks called Frames.
- Logical memory
(process) is divided into same size blocks called Pages.
- A Page Table
is used to map pages to frames.
Why
Paging?
✔
Avoids external fragmentation
✔ Allows non-contiguous memory allocation
✔ efficient memory utilization
Address
Translation in Paging
Logical
Address =
Page
Number (p) + Offset (d)
Physical
Address =
Frame
Number + Offset
Formula:
Physical
Address = Frame_Number × Frame_Size + Offset
Example
Suppose:
- Page size = 100
bytes
- Page table:
|
Page |
Frame |
|
0 |
2 |
|
1 |
0 |
|
2 |
1 |
|
3 |
3 |
Logical
Address = 250
Step 1:
Page number = 250 / 100 = 2
Offset = 250 % 100 = 50
Step 2:
From page table → Page 2 → Frame 1
Step 3:
Physical Address = 1 × 100 + 50 = 150
Program
for Paging:
This
program converts logical address to physical address.
#include <stdio.h>
int main()
{
int page_size, n, i;
int page_table[10];
int logical_address, page_number, offset, physical_address;
printf("Enter number of pages: ");
scanf("%d", &n);
printf("Enter page size: ");
scanf("%d", &page_size);
printf("Enter frame number for each page:\n");
for(i = 0; i < n; i++)
{
printf("Page %d -> Frame:
", i);
scanf("%d",
&page_table[i]);
}
printf("Enter logical address: ");
scanf("%d", &logical_address);
page_number = logical_address / page_size;
offset = logical_address % page_size;
if(page_number >= n)
{
printf("Invalid Page
Number!\n");
}
else
{
physical_address =
page_table[page_number] * page_size + offset;
printf("Page Number = %d\n",
page_number);
printf("Offset = %d\n",
offset);
printf("Physical Address =
%d\n", physical_address);
}
return 0;
}
OUTPUT:
Enter number of pages: 4
Enter page size: 100
Enter frame number for each page:
Page 0 -> Frame: 2
Page 1 -> Frame: 0
Page 2 -> Frame: 1
Page 3 -> Frame: 3
Enter logical address: 250
Page Number = 2
Offset = 50
Physical Address = 150
How
Program Works
- User enters:
- Number of pages
- Page size
- Page table
mapping
- Enter logical
address.
- Program
calculates:
- Page number
- Offset
- Finds frame from
page table.
- Calculates
physical address.
11. Implement Bankers Algorithm
for Dead Lock avoidance and prevention
Banker's
Algorithm (Deadlock Avoidance)
Concept
(Easy Explanation)
Banker’s
Algorithm is used for Deadlock Avoidance.
The
system will:
- Check whether the
request can be granted.
- Check whether the
system remains in a Safe State after allocation.
- If safe → Allocate
resources.
- If unsafe → Do not
allocate (avoid deadlock).
Important Terms
|
Term |
Meaning |
|
Available |
Free
resources available |
|
Max |
Maximum
resources a process may need |
|
Allocation |
Resources
currently allocated |
|
Need |
Remaining
need = Max – Allocation |
Formula:
Need[i][j]
= Max[i][j] – Allocation[i][j]
Program:
#include <stdio.h>
int main() {
int n, m, i, j, k;
printf("Enter number of processes: ");
scanf("%d", &n);
printf("Enter number of resources: ");
scanf("%d", &m);
int alloc[n][m], max[n][m], need[n][m];
int avail[m];
printf("\nEnter Allocation Matrix:\n");
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
scanf("%d",
&alloc[i][j]);
printf("\nEnter Max Matrix:\n");
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
scanf("%d",
&max[i][j]);
printf("\nEnter Available Resources:\n");
for(i = 0; i < m; i++)
scanf("%d", &avail[i]);
// Calculate Need matrix
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
need[i][j] = max[i][j] -
alloc[i][j];
int finish[n], safeSeq[n];
for(i = 0; i < n; i++)
finish[i] = 0;
int count = 0;
while(count < n) {
int found = 0;
for(i = 0; i < n; i++) {
if(finish[i] == 0) {
int flag = 0;
for(j = 0; j < m; j++) {
if(need[i][j] >
avail[j]) {
flag = 1;
break;
}
}
if(flag == 0) {
for(k = 0; k < m; k++)
avail[k] +=
alloc[i][k];
safeSeq[count++] = i;
finish[i] = 1;
found = 1;
}
}
}
if(found == 0) {
printf("\nSystem is NOT in
Safe State (Deadlock possible)\n");
return 0;
}
}
printf("\nSystem is in Safe State\nSafe Sequence: ");
for(i = 0; i < n; i++)
printf("P%d ", safeSeq[i]);
return 0;
}
OUTPUT:
Processes = 5
Resources = 3
Allocation:
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
Max:
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
Available:
3 3 2
System is in Safe State
Safe Sequence: P1 P3 P4 P0 P2
How It
Works (Step-by-Step)
- Calculate Need =
Max – Allocation
- Check if any
process need ≤ available
- If yes:
- Allocate
- Add its
allocation back to available
- Mark process
finished
- Repeat until all
processes finish
- If not possible →
unsafe state
Why It
Avoids Deadlock?
Because:
- It never allows
allocation that leads to unsafe state.
- It checks future
possibility before granting resources.
12. Simulate the following file
allocation strategies a) Sequential b) Indexed c) Linked
File
Allocation Strategies
File
allocation methods define how files are stored on disk blocks.
Sequential
Allocation
Concept
- File occupies continuous
blocks
- Blocks are
allocated one after another
- Very simple method
Example:
If file
starts at block 10 and size is 4 blocks →
Blocks = 10, 11, 12, 13
Advantages
✔
Simple
✔ Fast access
Disadvantages
✘
External fragmentation
✘ Difficult to increase file size
a)Program
Sequential Allocation:
#include <stdio.h>
int main() {
int start, length, i;
printf("Enter starting block: ");
scanf("%d", &start);
printf("Enter length of file (no. of blocks): ");
scanf("%d", &length);
printf("\nBlocks allocated are:\n");
for(i = 0; i < length; i++) {
printf("%d ", start + i);
}
return 0;
}
OUPUT:
Enter starting block: 5
Enter length of file: 4
Blocks allocated are:
5 6 7 8
Indexed
Allocation
Concept
- One block is used
as Index Block
- Index block stores
addresses of all file blocks
- Blocks can be anywhere
in disk
Structure:
Index
Block → [ 4 | 10 | 7 | 15 ]
Advantages
✔
No external fragmentation
✔ Easy to grow file
Disadvantages
✘
Extra memory for index block
b)Program
Indexed Allocation:
#include <stdio.h>
int main() {
int n, i, indexBlock;
printf("Enter index block: ");
scanf("%d", &indexBlock);
printf("Enter number of blocks needed: ");
scanf("%d", &n);
int blocks[n];
printf("Enter block numbers:\n");
for(i = 0; i < n; i++) {
scanf("%d", &blocks[i]);
}
printf("\nFile Indexed Allocation\n");
printf("Index Block: %d\n", indexBlock);
printf("Blocks are:\n");
for(i = 0; i < n; i++) {
printf("%d ", blocks[i]);
}
return 0;
}
OUTPUT:
Enter index block: 2
Enter number of blocks: 3
Enter block numbers:
5 9 12
Index Block: 2
Blocks are:
5 9 12
c)Program
Linked Allocation
#include <stdio.h>
int main() {
int n, i;
printf("Enter number of blocks: ");
scanf("%d", &n);
int blocks[n];
printf("Enter block numbers:\n");
for(i = 0; i < n; i++) {
scanf("%d", &blocks[i]);
}
printf("\nLinked File Allocation:\n");
for(i = 0; i < n - 1; i++) {
printf("%d -> ",
blocks[i]);
}
printf("%d -> NULL", blocks[n - 1]);
return 0;
}
OUTPUT:
Enter number of blocks: 4
Enter block numbers:
3 7 11 15
Linked File Allocation:
3 -> 7 -> 11 -> 15 ->
NULL
|
Feature |
Sequential |
Indexed |
Linked |
|
Storage |
Continuous |
Anywhere |
Anywhere |
|
Fragmentation |
Yes |
No |
No |
|
Random Access |
Fast |
Fast |
Slow |
|
File Growth |
Difficult |
Easy |
Easy |
|
Extra Memory |
No |
Index block |
Pointer |