OS_Lab_program_manual
OS_Lab_program_manual
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
pid_t pid;
int status;
printf("Starting main program...\n");
// Fork a child process
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork failed\n");
return 1;
} else if (pid == 0) {
// Child process
printf("Child process executing...\n");
// Executing a command using execl
execl("/bin/ls", "ls", "-l", NULL);
// This line will only be reached if execl fails
perror("execl");
exit(EXIT_FAILURE);
} else {
// Parent process
printf("Parent process waiting for child...\n");
// Wait for the child process to finish
wait(&status);
if (WIFEXITED(status)) {
printf("Child process terminated with status: %d\n", WEXITSTATUS(status));
} else {
printf("Child process terminated abnormally\n");
}
printf("Parent process exiting...\n");
}
return 0;
}
OUTPUT
Overview:
1. Initialization: Initialize the necessary variables including the buffer, semaphores (empty and full), and mutex.
2. Producer Function: Create a function for the producer thread that generates items and attempts to add
them to the shared buffer. Ensure synchronization by using semaphores and mutex to manage access to the
buffer.
3. Consumer Function: Develop a function for the consumer thread that retrieves items from the buffer.
Employ semaphores and mutex to control access to the shared buffer and prevent consumption when the
buffer is empty.
4. Main Function: In the main() function, create threads for both the producer and consumer. Manage thread
creation, execution, and termination using pthread_create() and pthread_join().
5. Cleanup: Properly destroy and release the resources such as semaphores and mutex used in the solution to
avoid memory leaks.
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int count = 0;
int in = 0;
int out = 0;
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
void *producer(void *arg) {
int item;
for (int i = 0; i < 10; ++i) {
item = i + 1; // Producing item
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = item;
printf("Produced: %d\n", item);
in = (in + 1) % BUFFER_SIZE;
count++;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
int item;
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
for (int i = 0; i < 10; ++i) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
item = buffer[out];
printf("Consumed: %d\n", item);
out = (out + 1) % BUFFER_SIZE;
count--;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
} pthread_exit(NULL);
} int main() {
pthread_t producerThread, consumerThread;
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
pthread_create(&producerThread, NULL, producer, NULL);
pthread_create(&consumerThread, NULL, consumer, NULL);
pthread_join(producerThread, NULL);
pthread_join(consumerThread, NULL);
sem_destroy(&empty);
sem_destroy(&full);
pthread_mutex_destroy(&mutex);
return 0;
}
***********************************************************
OUTPUT
opera@opera-virtual-machine:~/Desktop$ gcc -o 1 1.c -pthreads
opera@opera-virtual-machine:~/Desktop$ ./1
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Produced: 5
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Produced: 10
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9
Consumed: 10
opera@opera-virtual-machine:~/Desktop$
void writerProcess() {
int fd;
char *message = "Hello, reader!";
mkfifo(FIFO_NAME, 0666);
fd = open(FIFO_NAME, O_WRONLY);
write(fd, message, strlen(message) + 1);
close(fd);
void readerProcess() {
int fd;
char readMessage[100];
fd = open(FIFO_NAME, O_RDONLY);
read(fd, readMessage, sizeof(readMessage));
printf("Received message: %s\n", readMessage);
close(fd);
}
int main() {
pid_t pid;
// Create a child process
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork failed!\n");
return 1;
} else if (pid > 0) {
// Parent process (Writer)
writerProcess();
} else {
// Child process (Reader)
readerProcess();
}
return 0;
}
*******************************************************************
OUTPUT
opera@opera-virtual-machine:~/Desktop$ gcc -o 1 1.c
opera@opera-virtual-machine:~/Desktop$ ./1
Data sent to reader successfully! Received message: Hello, reader!
opera@opera-virtual-machine:~/Desktop$
Overview:
The program simulates the Banker's Algorithm for deadlock avoidance by taking input for the number of processes,
the number of resource types available, the maximum resources needed by each process, and the allocated
resources for each process.
1. Input Collection:
2. Initialization:
Initializes data structures for allocation, maximum, need, and finish arrays.
Initializes the need array by calculating the remaining need (maximum - allocated) for each process.
Initializes the finish array to track the finish status of each process.
Simulates the resource allocation by checking if processes can execute safely without causing a
deadlock.
4. Output:
If the system is in a safe state, displays the safe sequence of process execution to avoid deadlock.
#include <stdio.h>
#define MAX_PROCESSES 10
#define MAX_RESOURCES 10
int available[MAX_RESOURCES];
int allocation[MAX_PROCESSES][MAX_RESOURCES];
int need[MAX_PROCESSES][MAX_RESOURCES];
int finish[MAX_PROCESSES];
void input_data() {
printf("Enter number of processes and resources: ");
scanf("%d %d", &num_processes, &num_resources);
int is_safe() {
int work[MAX_RESOURCES];
for (int i = 0; i < num_resources; ++i)
work[i] = available[i];
int safe_sequence[MAX_PROCESSES];
int count = 0;
Overview:
The C program simulates memory allocation using three different strategies:
1. First Fit: This strategy allocates the first available memory block that is large enough to accommodate the
process.
2. Best Fit: Here, the program allocates the smallest available block that is sufficient for the process, minimizing
wasted memory.
3. Worst Fit: This strategy allocates the largest available memory block, leaving behind the biggest free chunk.
The program utilizes an array of memory blocks represented by a structure containing information about each block's
size and allocation status. The allocateMemory() function iterates through these blocks based on the chosen strategy
('F' for First Fit, 'B' for Best Fit, and 'W' for Worst Fit) to find and allocate memory for a given process size.
#include <stdio.h>
if (idx != -1) {
memory[idx].allocated = 1;
printf("Memory allocated for process of size %d using %c Fit at block %d\n", processSize, strategy, idx);
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
} else {
printf("Insufficient memory for process of size %d using %c Fit\n", processSize, strategy);
}
}
int main() {
struct MemoryBlock memory[] = {{100, 0}, {500, 0}, {200, 0}, {300, 0}}; // Memory blocks
return 0;
}
OUTPUT
Overview:
The C program includes implementations for the FIFO and LRU page replacement algorithms using an array-based
memory representation. Key components of the program include:
1. PageFrame Structure: This structure represents each frame in memory and holds information about the page
number stored in the frame and, in the case of LRU, the time the page was last used.
2. initializeFrames(): A function to initialize the page frames with default values indicating an empty frame.
3. displayFrames(): A function to display the current state of the page frames at any point during the
simulation.
4. fifo(): Implements the FIFO page replacement algorithm, simulating how pages are replaced when a page
fault occurs. It tracks the order of page references and replaces the oldest page based on the FIFO principle.
5. lru(): Implements the LRU page replacement algorithm, using the concept of time used to replace the least
recently used page upon a page fault.
6. Main Function: Contains the reference string representing page references and creates arrays to hold frames
for both FIFO and LRU algorithms. It invokes the FIFO and LRU functions, displaying the page frame states
and the total number of page faults for each algorithm.
#include <stdio.h>
#include <stdbool.h>
struct PageFrame {
int pageNumber;
int timeUsed;
};
if (!pageFound) {
frames[frameIndex].pageNumber = currentPage;
frameIndex = (frameIndex + 1) % MAX_FRAMES;
pageFaults++;
displayFrames(frames, MAX_FRAMES);
}
}
if (!pageFound) {
int leastUsedIdx = 0;
for (j = 1; j < MAX_FRAMES; ++j)
if (frames[j].timeUsed < frames[leastUsedIdx].timeUsed)
leastUsedIdx = j;
frames[leastUsedIdx].pageNumber = currentPage;
frames[leastUsedIdx].timeUsed = i;
pageFaults++;
displayFrames(frames, MAX_FRAMES);
Prof. S.N SGBIT, Belagavi
OPERATING SYSTEM LAB MANUAL BCS303
}
}
int main() {
int pageReferences[] = {2, 3, 2, 1, 5, 2, 4, 5, 3, 2, 5};
int numReferences = sizeof(pageReferences) / sizeof(pageReferences[0]);
return 0;
}
OUTPUT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FILES 10
#define MAX_NAME_LENGTH 20
typedef struct {
char name[MAX_NAME_LENGTH];
int isOccupied;
} File;
File singleLevelDirectory[MAX_FILES];
void initializeSingleLevelDirectory() {
OUTPUT
#define MAX_DIRECTORIES 5
#define MAX_FILES_PER_DIRECTORY 10
#define MAX_NAME_LENGTH 20
typedef struct {
char name[MAX_NAME_LENGTH];
int isOccupied;
} File;
typedef struct {
char name[MAX_NAME_LENGTH];
File files[MAX_FILES_PER_DIRECTORY];
} Directory;
Directory twoLevelDirectory[MAX_DIRECTORIES];
void initializeTwoLevelDirectory() {
for (int i = 0; i < MAX_DIRECTORIES; i++) {
twoLevelDirectory[i].name[0] = '\0';
for (int j = 0; j < MAX_FILES_PER_DIRECTORY; j++) {
twoLevelDirectory[i].files[j].isOccupied = 0;
}
}
}
int main() {
initializeTwoLevelDirectory();
strcpy(twoLevelDirectory[0].name, "dir1");
createFileTwoLevel("file1.txt", "dir1");
createFileTwoLevel("file2.txt", "dir1");
searchFileTwoLevel("file1.txt", "dir1");
searchFileTwoLevel("file3.txt", "dir1");
deleteFileTwoLevel("file2.txt", "dir1");
deleteFileTwoLevel("file3.txt", "dir1");
return 0;
}
OUTPUT
#include <stdio.h>
#include <stdlib.h>
#define MAX_BLOCKS 50
Block disk[MAX_BLOCKS];
void initializeDisk() {
for (int i = 0; i < MAX_BLOCKS; i++) {
disk[i].data = 0;
disk[i].next = NULL;
}
}
int allocateBlock() {
for (int i = 0; i < MAX_BLOCKS; i++) {
if (disk[i].data == 0) {
disk[i].data = 1; // Mark the block as allocated
return i; // Return the index of the allocated block
}
}
return -1; // No available block
}
return 0;
}
OUTPUT
#include <stdio.h>
#include <stdlib.h>
int main() {
int numRequests, initialPosition;