Beruflich Dokumente
Kultur Dokumente
CODE: -
#include <stdio.h>
//user-defined function
int findLRU(int time[], int n)
{
int i, minimum = time[0], pos = 0;
for (i = 1; i < n; ++i)
{
if (time[i] < minimum)
{
minimum = time[i];
pos = i;
}
}
return pos;
}
//main function
int main()
{
int no_of_frames, no_of_pages, frames[10], pages[30], counter = 0, time[10], flag1,
flag2, i, j, pos, faults = 0;
printf("Enter number of frames: ");
scanf("%d", &no_of_frames);
printf("Enter number of pages: ");
scanf("%d", &no_of_pages);
printf("Enter reference string: ");
for (i = 0; i < no_of_pages; ++i)
{
scanf("%d", &pages[i]);
}
for (i = 0; i < no_of_frames; ++i)
{
frames[i] = -1;
}
for (i = 0; i < no_of_pages; ++i)
{
flag1 = flag2 = 0;
for (j = 0; j < no_of_frames; ++j)
{
if (frames[j] == pages[i])
{
counter++;
time[j] = counter;
flag1 = flag2 = 1;
break;
}
}
if (flag1 == 0)
{
for (j = 0; j < no_of_frames; ++j)
{
if (frames[j] == -1)
{
counter++;
faults++;
frames[j] = pages[i];
time[j] = counter;
flag2 = 1;
break;
}
}
}
if (flag2 == 0)
{
pos = findLRU(time, no_of_frames);
counter++;
faults++;
frames[pos] = pages[i];
time[pos] = counter;
}
printf("\n");
for (j = 0; j < no_of_frames; ++j)
{
printf("%d\t", frames[j]);
}
}
printf("\nTotal Page Faults = %d", faults);
return 0;
}
OUTPUT: -
EXPERIMENT – 8
AIM: - Implementation of FIFO page replacement policy.
THEORY: -
FIFO which is also known as First In First Out is one of the types of page replacement
algorithm. The FIFO algorithm is used in the paging method for memory management in an
operating system that decides which existing page needs to be replaced in the queue. FIFO
algorithm replaces the oldest (First) page which has been present for the longest time in the
main memory.
Advantages of FIFO Page Replacement Algorithm
FIFO page replacement algorithm is commonly known for its simplicity.
FIFO algorithm is much easy to implement as well as understand.
Small systems can use the FIFO algorithm efficiently.
Disadvantages of FIFO Page Replacement Algorithm
FIFO algorithm in os uses an additional ==Queue== data structure.
It suffers from ==Belady's anomaly== problem i.e when the number of page frames
increases, more memory is given to processes, but instead of decreasing, the number
of page faults increases.
CODE: -
#include<stdio.h>
int main()
{
int incomingStream[] = {4, 1, 2, 4, 5};
int pageFaults = 0;
int frames = 3;
int m, n, s, pages;
pages = sizeof(incomingStream)/sizeof(incomingStream[0]);
printf("Incoming \t Frame 1 \t Frame 2 \t Frame 3");
int temp[frames];
for(m = 0; m < frames; m++)
{
temp[m] = -1;
}
for (m = 0; m < pages; m++)
{
s = 0;
for(n = 0; n < frames; n++)
{
if(incomingStream[m] == temp[n])
{
s++;
pageFaults--;
}
}
pageFaults++;
if((pageFaults <= frames) && (s == 0))
{
temp[m] = incomingStream[m];
}
else if(s == 0)
{
temp[(pageFaults - 1) % frames] = incomingStream[m];
}
printf("\n");
printf("%d\t\t\t",incomingStream[m]);
for(n = 0; n < frames; n++)
{
if(temp[n] != -1)
printf(" %d\t\t\t", temp[n]);
else
printf(" - \t\t\t");
}
}
printf("\nTotal Page Faults:\t%d\n", pageFaults);
return 0;
}
OUTPUT: -
EXPERIMENT – 9
AIM: - Implementation of OPTIMAL page replacement policy.
THEORY: -
The optimal page replacement algorithm is used to reduce these page faults. It uses the
principle that- "when a page is called by the system and it is not available in the frames, the
frame which is not in demand for the longest future time is replaced by the new page".
Advantages Of Optimal Page Replacement Algorithm:
Following are the advantages of the Optimal page replacement algorithm:
Least page fault occurs as this algorithm replaces the page that is not going to be used
for the longest time in the future.
In this algorithm, Belady's Anomaly (the number of page faults increases when we
increase the number of frames in secondary storage) does not occur because this
algorithm uses a 'stack-based algorithm' for page replacement.
Data structure used in this algorithm is easy to understand.
The page that will not be in demand in the future time is replaced by a new page in
the frames.
Disadvantages Of Optimal Page Replacement Algorithm:
Following are the disadvantages of the optimal page replacement algorithm:
This algorithm is limited to some specific operating systems. All OS cannot use this.
Detecting error in this algorithm is not so easy.
Sometimes, the page which is used recently is replaced which takes much time.
This algorithm is difficult to implement because the operating system can't predict the
future reference strings.
CODE: -
#include <stdio.h>
// This function checks if current strea item(key) exists in any of the frames or not
int search(int key, int frame_items[], int frame_occupied)
{
for (int i = 0; i < frame_occupied; i++)
if (frame_items[i] == key)
return 1;
return 0;
}
void printOuterStructure(int max_frames){
printf("Stream ");
for(int i = 0; i < max_frames; i++)
printf("Frame%d ", i+1);
}
void printCurrFrames(int item, int frame_items[], int frame_occupied, int max_frames){
// print current reference stream item
printf("\n%d \t\t", item);
// print frame occupants one by one
for(int i = 0; i < max_frames; i++){
if(i < frame_occupied)
printf("%d \t\t", frame_items[i]);
else
printf("- \t\t");
}
}
// This Function helps in finding frame that will not be used
// for the longest period of time in future in ref_str[0 ... refStrLen - 1]
int predict(int ref_str[], int frame_items[], int refStrLen, int index, int frame_occupied)
{
// For each current occupant in frame item
// we try to find the frame item that will not be referenced in
// for the longest in future in the upcoming reference string
int result = -1, farthest = index;
for (int i = 0; i < frame_occupied; i++) {
int j;
for (j = index; j < refStrLen; j++)
{
if (frame_items[i] == ref_str[j])
{
if (j > farthest) {
farthest = j;
result = i;
}
break;
}
}
// If we find a page that is never referenced in future,
// return it immediately as its the best
if (j == refStrLen)
return i;
}
// If none of the frame items appear in reference string
// in the future then we return 0th index. Otherwise we return result
return (result == -1) ? 0 : result;
}
void optimalPage(int ref_str[], int refStrLen, int frame_items[], int max_frames)
{
// initially none of the frames are occupied
int frame_occupied = 0;
printOuterStructure(max_frames);
// Here we traverse through reference string
// and check for miss and hit.
int hits = 0;
for (int i = 0; i < refStrLen; i++) {
// If found already in the frame items : HIT
if (search(ref_str[i], frame_items, frame_occupied)) {
hits++;
printCurrFrames(ref_str[i], frame_items, frame_occupied, max_frames);
continue;
}
// If frames are empty then current reference string item in frame
if (frame_occupied < max_frames){
frame_items[frame_occupied] = ref_str[i];
frame_occupied++;
printCurrFrames(ref_str[i], frame_items, frame_occupied, max_frames);
}else {
int pos = predict(ref_str, frame_items, refStrLen, i + 1, frame_occupied);
frame_items[pos] = ref_str[i];
printCurrFrames(ref_str[i], frame_items, frame_occupied, max_frames);
}
}
printf("\n\nHits: %d\n", hits);
printf("Misses: %d", refStrLen - hits);
}
// Driver Function
int main()
{
// int ref_str[] = {9, 0, 5, 1, 0, 3, 0, 4, 1, 3, 0, 3, 1, 3};
int ref_str[] = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1};
int refStrLen = sizeof(ref_str) / sizeof(ref_str[0]);
int max_frames = 3;
int frame_items[max_frames];
optimalPage(ref_str, refStrLen, frame_items, max_frames);
return 0;
}
OUTPUT: -
EXPERIMENT – 10
AIM: - Implementation of FIRST FIT algorithm for memory management.
THEORY: -
First-Fit Allocation is a memory allocation technique used in operating systems to allocate
memory to a process. In First-Fit, the operating system searches through the list of free
blocks of memory, starting from the beginning of the list, until it finds a block that is large
enough to accommodate the memory request from the process. Once a suitable block is
found, the operating system splits the block into two parts: the portion that will be allocated
to the process, and the remaining free block.
Advantages of First-Fit Allocation include its simplicity and efficiency, as the search for a
suitable block of memory can be performed quickly and easily. Additionally, First-Fit can
also help to minimize memory fragmentation, as it tends to allocate memory in larger blocks.
Disadvantages of First-Fit Allocation include poor performance in situations where the
memory is highly fragmented, as the search for a suitable block of memory can become time-
consuming and inefficient. Additionally, First-Fit can also lead to poor memory utilization, as
it may allocate larger blocks of memory than are needed by a process.
Overall, First-Fit Allocation is a widely used memory allocation technique in operating
systems, but its effectiveness may vary depending on the specifics of the system and the
workload being executed.
CODE: -
#include<stdio.h>
void main()
{
int bsize[10], psize[10], bno, pno, flags[10], allocation[10], i, j;
for(i = 0; i < 10; i++)
{
flags[i] = 0;
allocation[i] = -1;
}
printf("Enter no. of blocks: ");
scanf("%d", &bno);
printf("\nEnter size of each block: ");
for(i = 0; i < bno; i++)
scanf("%d", &bsize[i]);
printf("\nEnter no. of processes: ");
scanf("%d", &pno);
printf("\nEnter size of each process: ");
for(i = 0; i < pno; i++)
scanf("%d", &psize[i]);
for(i = 0; i < pno; i++) //allocation as per first fit
for(j = 0; j < bno; j++)
if(flags[j] == 0 && bsize[j] >= psize[i])
{
allocation[j] = i;
flags[j] = 1;
break;
}
//display allocation details
printf("\nBlock no.\tsize\t\tprocess no.\t\tsize");
for(i = 0; i < bno; i++)
{
printf("\n%d\t\t%d\t\t", i+1, bsize[i]);
if(flags[i] == 1)
printf("%d\t\t\t%d",allocation[i]+1,psize[allocation[i]]);
else
printf("Not allocated");
}
}
OUTPUT: -
EXPERIMENT – 11
AIM: - Implementation of BEST FIT algorithm for memory management.
THEORY: -
Best-Fit Allocation is a memory allocation technique used in operating systems to allocate
memory to a process. In Best-Fit, the operating system searches through the list of free blocks
of memory to find the block that is closest in size to the memory request from the process.
Once a suitable block is found, the operating system splits the block into two parts: the
portion that will be allocated to the process, and the remaining free block.
Advantages of Best-Fit Allocation include improved memory utilization, as it allocates the
smallest block of memory that is sufficient to accommodate the memory request from the
process. Additionally, Best-Fit can also help to reduce memory fragmentation, as it tends to
allocate smaller blocks of memory that are less likely to become fragmented.
Disadvantages of Best-Fit Allocation include increased computational overhead, as the
search for the best-fit block of memory can be time-consuming and requires a more complex
search algorithm. Additionally, Best-Fit may also result in increased fragmentation, as it may
leave smaller blocks of memory scattered throughout the memory space.
Overall, Best-Fit Allocation is a widely used memory allocation technique in operating
systems, but its effectiveness may vary depending on the specifics of the system and the
workload being executed.
CODE: -
#include<stdio.h>
void main()
{
int fragment[20],b[20],p[20],i,j,nb,np,temp,lowest=9999;
static int barray[20],parray[20];
printf("\n\t\t\tMemory Management Scheme - Best Fit");
printf("\nEnter the number of blocks:");
scanf("%d",&nb);
printf("Enter the number of processes:");
scanf("%d",&np);
printf("\nEnter the size of the blocks:-\n");
for(i=1;i<=nb;i++)
{
printf("Block no.%d:",i);
scanf("%d",&b[i]);
}
printf("\nEnter the size of the processes :-\n");
for(i=1;i<=np;i++)
{
printf("Process no.%d:",i);
scanf("%d",&p[i]);
}
for(i=1;i<=np;i++)
{
for(j=1;j<=nb;j++)
{
if(barray[j]!=1)
{
temp=b[j]-p[i];
if(temp>=0)
if(lowest>temp)
{
parray[i]=j;
lowest=temp;
}
}
}
fragment[i]=lowest;
barray[parray[i]]=1;
lowest=10000;
}
printf("\nProcess_no\tProcess_size\tBlock_no\tBlock_size\tFragment");
for(i=1;i<=np && parray[i]!=0;i++)
printf("\n%d\t\t%d\t\t%d\t\t%d\t\t%d",i,p[i],parray[i],b[parray[i]],fragment[i]);
}
OUTPUT: -
EXPERIMENT – 12
AIM: - Implementation of WORST FIT algorithm for memory management.
THEORY: -
In this allocation technique, the process traverses the whole memory and always search for
the largest hole/partition, and then the process is placed in that hole/partition. It is a slow
process because it has to traverse the entire memory to search the largest hole.
Here is an example to understand Worst Fit-Allocation –
Here Process P1=30K is allocated with the Worst Fit-Allocation technique, so it traverses the
entire memory and selects memory size 400K which is the largest, and hence there is an
internal fragmentation of 370K which is very large and so many other processes can also
utilize this leftover space.
Advantage:
Since this process chooses the largest hole/partition, therefore there will be large internal
fragmentation. Now, this internal fragmentation will be quite big so that other small
processes can also be placed in that leftover partition.
Disadvantage:
It is a slow process because it traverses all the partitions in the memory and then selects the
largest partition among all the partitions, which is a time-consuming process.
CODE: -
#include <stdio.h>
void implimentWorstFit(int blockSize[], int blocks, int processSize[], int processes)
{
// This will store the block id of the allocated block to a process
int allocation[processes];
int occupied[blocks];
// initially assigning -1 to all allocation indexes
// means nothing is allocated currently
for(int i = 0; i < processes; i++){
allocation[i] = -1;
}
for(int i = 0; i < blocks; i++){
occupied[i] = 0;
}
// pick each process and find suitable blocks
// according to its size ad assign to it
for (int i=0; i < processes; i++)
{
int indexPlaced = -1;
for(int j = 0; j < blocks; j++)
{
// if not occupied and block size is large enough
if(blockSize[j] >= processSize[i] && !occupied[j])
{
// place it at the first block fit to accomodate process
if (indexPlaced == -1)
indexPlaced = j;
// if any future block is larger than the current block where
// process is placed, change the block and thus indexPlaced
else if (blockSize[indexPlaced] < blockSize[j])
indexPlaced = j;
}
}
// If we were successfully able to find block for the process
if (indexPlaced != -1)
{
// allocate this block j to process p[i]
allocation[i] = indexPlaced;
// make the status of the block as occupied
occupied[indexPlaced] = 1:
// Reduce available memory for the block
blockSize[indexPlaced] -= processSize[i];
}
}
printf("\nProcess No.\tProcess Size\tBlock no.\n");
for (int i = 0; i < processes; i++)
{
printf("%d \t\t\t %d \t\t\t", i+1, processSize[i]);
if (allocation[i] != -1)
printf("%d\n",allocation[i] + 1);
else
printf("Not Allocated\n");
}
}
// Driver code
int main()
{
int blockSize[] = {100, 50, 30, 120, 35};
int processSize[] = {40, 10, 30, 60};
int blocks = sizeof(blockSize)/sizeof(blockSize[0]);
int processes = sizeof(processSize)/sizeof(processSize[0]);
implimentWorstFit(blockSize, blocks, processSize, processes);
return 0;
}
OUTPUT: -
EXPERIMENT – 13
AIM: - Implementation of READER/WRITER problem using semaphore.
THEORY: -
The readers-writers problem relates to an object such as a file that is shared between multiple
processes. Some of these processes are readers i.e., they only want to read the data from the
object and some of the processes are writers i.e. they want to write into the object.
The readers-writers problem is used to manage synchronization so that there are no problems
with the object data. For example - If two readers access the object at the same time there is
no problem. However, if two writers or a reader and writer access the object at the same time,
there may be problems.
To solve this situation, a writer should get exclusive access to an object i.e. when a writer is
accessing the object, no reader or writer may access it. However, multiple readers can access
the object at the same time.
This can be implemented using semaphores. The codes for the reader and writer process in
the reader-writer problem are given as follows −
Reader Process
The code that defines the reader process is given below −
wait (mutex);
rc ++;
if (rc == 1)
wait (wrt);
signal(mutex);
.
. READ THE OBJECT
.
wait(mutex);
rc --;
if (rc == 0)
signal (wrt);
signal(mutex);
Writer Process
The code that defines the writer process is given below:
wait(wrt);
.
. WRITE INTO THE OBJECT
.
signal(wrt);
CODE: -
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_READERS 5
#define NUM_WRITERS 2
return NULL;
}
int main() {
srand(time(NULL));
// Initialize semaphores
sem_init(&mutex, 0, 1);
sem_init(&writeBlock, 0, 1);
// Create reader threads
pthread_t readers[NUM_READERS];
int reader_ids[NUM_READERS];
for (int i = 0; i < NUM_READERS; ++i) {
reader_ids[i] = i;
pthread_create(&readers[i], NULL, reader, &reader_ids[i]);
}
// Create writer threads
pthread_t writers[NUM_WRITERS];
int writer_ids[NUM_WRITERS];
for (int i = 0; i < NUM_WRITERS; ++i) {
writer_ids[i] = i;
pthread_create(&writers[i], NULL, writer, &writer_ids[i]);
}
// Wait for reader threads to finish
for (int i = 0; i < NUM_READERS; ++i) {
pthread_join(readers[i], NULL);
}
// Wait for writer threads to finish
for (int i = 0; i < NUM_WRITERS; ++i) {
pthread_join(writers[i], NULL);
}
// Destroy semaphores
sem_destroy(&mutex);
sem_destroy(&writeBlock);
return 0;
}
OUTPUT: -
EXPERIMENT – 14
AIM: - Implementation of BANKER’S algorithm for deadlock avoidance.
THEORY: -
The banker’s algorithm is a resource allocation and deadlock avoidance algorithm that tests
for safety by simulating the allocation for the predetermined maximum possible amounts of
all resources, then makes an “s-state” check to test for possible activities, before deciding
whether allocation should be allowed to continue.
Advantages
Following are the essential characteristics of the Banker's algorithm:
1. It contains various resources that meet the requirements of each process.
2. Each process should provide information to the operating system for upcoming
resource requests, the number of resources, and how long the resources will be held.
3. It helps the operating system manage and control process requests for each type of
resource in the computer system.
4. The algorithm has a Max resource attribute that represents indicates each process can
hold the maximum number of resources in a system.
Disadvantages
1. It requires a fixed number of processes, and no additional processes can be started in
the system while executing the process.
2. The algorithm does no longer allows the processes to exchange its maximum needs
while processing its tasks.
3. Each process has to know and state their maximum resource requirement in advance
for the system.
4. The number of resource requests can be granted in a finite time, but the time limit for
allocating the resources is one year.
CODE: -
#include <stdio.h>
int main()
{
// P0, P1, P2, P3, P4 are the Process names here
int n, m, i, j, k;
n = 5; // Number of processes
m = 3; // Number of resources
int alloc[5][3] = { { 0, 1, 0 }, // P0 // Allocation Matrix
{ 2, 0, 0 }, // P1
{ 3, 0, 2 }, // P2
{ 2, 1, 1 }, // P3
{ 0, 0, 2 } }; // P4
int max[5][3] = { { 7, 5, 3 }, // P0 // MAX Matrix
{ 3, 2, 2 }, // P1
{ 9, 0, 2 }, // P2
{ 2, 2, 2 }, // P3
{ 4, 3, 3 } }; // P4
int avail[3] = { 3, 3, 2 }; // Available Resources
int f[n], ans[n], ind = 0;
for (k = 0; k < n; k++) {
f[k] = 0;
}
int need[n][m];
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++)
need[i][j] = max[i][j] - alloc[i][j];
}
int y = 0;
for (k = 0; k < 5; k++) {
for (i = 0; i < n; i++) {
if (f[i] == 0) {
int flag = 0;
for (j = 0; j < m; j++) {
if (need[i][j] > avail[j]){
flag = 1;
break;
}
}
if (flag == 0) {
ans[ind++] = i;
for (y = 0; y < m; y++)
avail[y] += alloc[i][y];
f[i] = 1;
}
}
}
}
int flag = 1;
for(int i=0;i<n;i++)
{
if(f[i]==0)
{
flag=0;
printf("The following system is not safe");
break;
}
}
if(flag==1)
{
printf("Following is the SAFE Sequence\n");
for (i = 0; i < n - 1; i++)
printf(" P%d ->", ans[i]);
printf(" P%d", ans[n - 1]);
}
return (0):
}
OUTPUT: -
EXPERIMENT – 15
AIM: - Implementation of DINING PHILOSOPHER problem.
THEORY: -
The dining philosopher's problem is the classical problem of synchronization which says that
Five philosophers are sitting around a circular table and their job is to think and eat
alternatively. A bowl of noodles is placed at the center of the table along with five chopsticks
for each of the philosophers. To eat a philosopher needs both their right and a left chopstick.
A philosopher can only eat if both immediate left and right chopsticks of the philosopher is
available. In case if both immediate left and right chopsticks of the philosopher are not
available then the philosopher puts down their (either left or right) chopstick and starts
thinking again.
CODE: -
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define NUM_PHILOSOPHERS 5
#define NUM_EATING_ITERATIONS 3
pthread_mutex_t forks[NUM_PHILOSOPHERS];
pthread_t philosophers[NUM_PHILOSOPHERS];
void *philosopher(void *arg) {
int id = *(int *)arg;
int left_fork = id;
int right_fork = (id + 1) % NUM_PHILOSOPHERS;
for (int i = 0; i < NUM_EATING_ITERATIONS; ++i) {
// Thinking
printf("Philosopher %d is thinking.\n", id);
sleep(rand() % 3 + 1);
// Pick up left fork
pthread_mutex_lock(&forks[left_fork]);
printf("Philosopher %d picked up left fork.\n", id);
// Pick up right fork
pthread_mutex_lock(&forks[right_fork]);
printf("Philosopher %d picked up right fork.\n", id);
// Eating
printf("Philosopher %d is eating.\n", id);
sleep(rand() % 3 + 1);
// Put down right fork
pthread_mutex_unlock(&forks[right_fork]);
printf("Philosopher %d put down right fork.\n", id);
// Put down left fork
pthread_mutex_unlock(&forks[left_fork]);
printf("Philosopher %d put down left fork.\n", id);
}
return NULL;
}
int main() {
srand(time(NULL));
// Initialize forks mutexes
for (int i = 0; i < NUM_PHILOSOPHERS; ++i) {
pthread_mutex_init(&forks[i], NULL);
}
// Create philosopher threads
int philosopher_ids[NUM_PHILOSOPHERS];
for (int i = 0; i < NUM_PHILOSOPHERS; ++i) {
philosopher_ids[i] = i;
pthread_create(&philosophers[i], NULL, philosopher, &philosopher_ids[i]);
}
// Wait for philosopher threads to finish
for (int i = 0; i < NUM_PHILOSOPHERS; ++i) {
pthread_join(philosophers[i], NULL);
}
OUTPUT: -