xae
Q.Write a shell program to find even or odd
number.
#!/bin/bash
Prompt the user to enter a number
echo "Enter a number: "
read num
Check if the number is divisible by 2
if (( num % 2 == 0 )); then
echo "num is odd."
fi
Q. Write a shell program to display list of even numbers from 1 to 100.
#!/bin/bash
echo "Even numbers from 2 to 100:"
for (( i = 2; i <= 100; i+=2 )); do
echo "$i"
done
Q. Write program to implement SJF
#include<stdio.h>
// Structure to represent a process
struct Process {
int id; // Process ID
int arrival_time; // Arrival time
int burst_time; // Burst time
int waiting_time; // Waiting time
int turnaround_time;// Turnaround time
};
// Function to perform SJF scheduling
void SJF(struct Process processes[], int n) {
// Sort the processes based on arrival time
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (processes[j].arrival_time > processes[j + 1].arrival_time) {
struct Process temp = processes[j];
processes[j] = processes[j + 1];
processes[j + 1] = temp;
}
}
}
int total_waiting_time = 0, total_turnaround_time = 0;
int current_time = 0;
// Calculate waiting time and turnaround time for each process
for (int i = 0; i < n; i++) {
// Update current time
current_time += processes[i].burst_time;
// Calculate waiting time for current process
processes[i].waiting_time = current_time - processes[i].burst_time - processes[i].arrival_time;
total_waiting_time += processes[i].waiting_time;
// Calculate turnaround time for current process
processes[i].turnaround_time = current_time - processes[i].arrival_time;
total_turnaround_time += processes[i].turnaround_time;
}
// Print the scheduling table
printf("Process ID\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n", processes[i].id, processes[i].arrival_time, processes[i].burst_time, processes[i].waiting_time, processes[i].turnaround_time);
}
// Calculate and print average waiting time and turnaround time
printf("Average Waiting Time: %.2f\n", (float) total_waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float) total_turnaround_time / n);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
// Input details of each process
struct Process processes[n];
for (int i = 0; i < n; i++) {
processes[i].id = i + 1;
printf("Enter arrival time for process %d: ", i + 1);
scanf("%d", &processes[i].arrival_time);
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &processes[i].burst_time);
}
// Perform SJF scheduling
SJF(processes, n);
return 0;
}
Q. PROGRAM TO IMPLEMENT FCFS
#include<stdio.h>
// Structure to represent a process
struct Process {
int id; // Process ID
int arrival_time; // Arrival time
int burst_time; // Burst time
int waiting_time; // Waiting time
int turnaround_time;// Turnaround time
};
// Function to perform FCFS scheduling
void FCFS(struct Process processes[], int n) {
int total_waiting_time = 0, total_turnaround_time = 0;
int current_time = 0;
// Calculate waiting time and turnaround time for each process
for (int i = 0; i < n; i++) {
// Update current time if arrival time of current process is greater than current time
if (current_time < processes[i].arrival_time) {
current_time = processes[i].arrival_time;
}
// Calculate waiting time for current process
processes[i].waiting_time = current_time - processes[i].arrival_time;
total_waiting_time += processes[i].waiting_time;
// Calculate turnaround time for current process
processes[i].turnaround_time = processes[i].burst_time + processes[i].waiting_time;
total_turnaround_time += processes[i].turnaround_time;
// Update current time
current_time += processes[i].burst_time;
}
// Print the scheduling table
printf("Process ID\tArrival Time\tBurst Time\tWaiting Time\tTurnaround Time\n");
for (int i = 0; i < n; i++) {
printf("%d\t\t%d\t\t%d\t\t%d\t\t%d\n", processes[i].id, processes[i].arrival_time, processes[i].burst_time, processes[i].waiting_time, processes[i].turnaround_time);
}
// Calculate and print average waiting time and turnaround time
printf("Average Waiting Time: %.2f\n", (float) total_waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float) total_turnaround_time / n);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
// Input details of each process
struct Process processes[n];
for (int i = 0; i < n; i++) {
processes[i].id = i + 1;
printf("Enter arrival time for process %d: ", i + 1);
scanf("%d", &processes[i].arrival_time);
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &processes[i].burst_time);
}
// Perform FCFS scheduling
FCFS(processes, n);
return 0;
}
Q. Write program to
implement RR algorithm.
#include <stdio.h>
#define MAX_PROCESSES 10
#define TIME_QUANTUM 2
// Structure to represent a process
struct Process {
int id; // Process ID
int burst_time; // Burst time
int remaining_time; // Remaining burst time
int arrival_time; // Arrival time
int waiting_time; // Waiting time
int turnaround_time;// Turnaround time
};
// Function to perform Round Robin scheduling
void RR(struct Process processes[], int n) {
int total_waiting_time = 0, total_turnaround_time = 0;
int current_time = 0;
int completed_processes = 0;
// Run the RR algorithm until all processes are completed
while (completed_processes < n) {
for (int i = 0; i < n; i++) {
// If process has arrived and has remaining burst time
if (processes[i].arrival_time <= current_time && processes[i].remaining_time > 0) {
// Execute the process for the time quantum or remaining burst time, whichever is smaller
int execute_time = (processes[i].remaining_time > TIME_QUANTUM) ? TIME_QUANTUM : processes[i].remaining_time;
current_time += execute_time;
processes[i].remaining_time -= execute_time;
// Update waiting time for other processes
for (int j = 0; j < n; j++) {
if (j != i && processes[j].arrival_time <= current_time && processes[j].remaining_time > 0) {
processes[j].waiting_time += execute_time;
}
}
// If process has completed its burst time
if (processes[i].remaining_time == 0) {
completed_processes++;
// Calculate turnaround time for the completed process
processes[i].turnaround_time = current_time - processes[i].arrival_time;
total_turnaround_time += processes[i].turnaround_time;
}
}
}
}
// Calculate and print average waiting time and turnaround time
for (int i = 0; i < n; i++) {
total_waiting_time += processes[i].waiting_time;
}
printf("Average Waiting Time: %.2f\n", (float) total_waiting_time / n);
printf("Average Turnaround Time: %.2f\n", (float) total_turnaround_time / n);
}
int main() {
int n;
printf("Enter the number of processes: ");
scanf("%d", &n);
// Input details of each process
struct Process processes[MAX_PROCESSES];
for (int i = 0; i < n; i++) {
processes[i].id = i + 1;
printf("Enter arrival time for process %d: ", i + 1);
scanf("%d", &processes[i].arrival_time);
printf("Enter burst time for process %d: ", i + 1);
scanf("%d", &processes[i].burst_time);
processes[i].remaining_time = processes[i].burst_time;
processes[i].waiting_time = 0;
processes[i].turnaround_time = 0;
}
// Perform RR scheduling
RR(processes, n);
return 0;
}
Q. Write Program to implement IPC
using shared memory
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#define SHM_SIZE 1024
int main() {
int shmid;
key_t key;
char *shm, *s;
// Generate a unique key for the shared memory segment
if ((key = ftok(".", 'R')) == -1) {
perror("ftok");
exit(1);
}
// Create the shared memory segment
if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666)) == -1) {
perror("shmget");
exit(1);
}
// Attach the shared memory segment
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {
perror("shmat");
exit(1);
}
// Write to the shared memory
printf("Enter message: ");
fgets(shm, SHM_SIZE, stdin);
// Wait for the receiver to read the message
while (*shm != '*')
sleep(1);
printf("Message received by receiver: %s", shm);
// Detach the shared memory segment
if (shmdt(shm) == -1) {
perror("shmdt");
exit(1);
}
// Delete the shared memory segment
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(1);
}
return 0;
}
Q. Write Program to implement
Producer-Consumer problem using semaphores
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define BUFFER_SIZE 5
#define NUM_PRODUCERS 2
#define NUM_CONSUMERS 2
#define NUM_ITEMS 10
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
sem_t empty, full, mutex;
void *producer(void *arg) {
int item;
for (int i = 0; i < NUM_ITEMS; i++) {
item = rand() % 100; // Generate a random item
sem_wait(&empty); // Wait for an empty slot in the buffer
sem_wait(&mutex); // Lock the critical section
buffer[in] = item;
printf("Producer %ld produced item %d\n", (long)arg, item);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex); // Unlock the critical section
sem_post(&full); // Signal that a slot in the buffer is full
sleep(1); // Simulate some work
}
pthread_exit(NULL);
}
void *consumer(void *arg) {
int item;
for (int i = 0; i < NUM_ITEMS; i++) {
sem_wait(&full); // Wait for a full slot in the buffer
sem_wait(&mutex); // Lock the critical section
item = buffer[out];
printf("Consumer %ld consumed item %d\n", (long)arg, item);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex); // Unlock the critical section
sem_post(&empty); // Signal that a slot in the buffer is empty
sleep(2); // Simulate some work
}
pthread_exit(NULL);
}
int main() {
pthread_t producer_threads[NUM_PRODUCERS];
pthread_t consumer_threads[NUM_CONSUMERS];
// Initialize semaphores
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
// Create producer threads
for (long i = 0; i < NUM_PRODUCERS; i++) {
pthread_create(&producer_threads[i], NULL, producer, (void *)i);
}
// Create consumer threads
for (long i = 0; i < NUM_CONSUMERS; i++) {
pthread_create(&consumer_threads[i], NULL, consumer, (void *)i);
}
// Join producer threads
for (int i = 0; i < NUM_PRODUCERS; i++) {
pthread_join(producer_threads[i], NULL);
}
// Join consumer threads
for (int i = 0; i < NUM_CONSUMERS; i++) {
pthread_join(consumer_threads[i], NULL);
}
// Destroy semaphores
sem_destroy(&empty);
sem_destroy(&full);
sem_destroy(&mutex);
return 0;
}
Q. Write Program to
implement Dining Philosopher problem using semaphores
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define NUM_PHILOSOPHERS 5
#define THINKING 0
#define HUNGRY 1
#define EATING 2
sem_t mutex;
sem_t phil_sem[NUM_PHILOSOPHERS];
int state[NUM_PHILOSOPHERS];
void test(int philosopher_id) {
if (state[philosopher_id] == HUNGRY &&
state[(philosopher_id + 1) % NUM_PHILOSOPHERS] != EATING &&
state[(philosopher_id + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS] != EATING) {
state[philosopher_id] = EATING;
printf("Philosopher %d is eating\n", philosopher_id);
sem_post(&phil_sem[philosopher_id]);
}
}
void grab_forks(int philosopher_id) {
sem_wait(&mutex);
state[philosopher_id] = HUNGRY;
printf("Philosopher %d is hungry\n", philosopher_id);
test(philosopher_id);
sem_post(&mutex);
sem_wait(&phil_sem[philosopher_id]);
}
void put_forks(int philosopher_id) {
sem_wait(&mutex);
state[philosopher_id] = THINKING;
printf("Philosopher %d is thinking\n", philosopher_id);
test((philosopher_id + 1) % NUM_PHILOSOPHERS);
test((philosopher_id + NUM_PHILOSOPHERS - 1) % NUM_PHILOSOPHERS);
sem_post(&mutex);
}
void *philosopher(void *arg) {
int philosopher_id = *(int *)arg;
while (1) {
// Simulate thinking
sleep(rand() % 3);
grab_forks(philosopher_id);
// Simulate eating
sleep(rand() % 3);
put_forks(philosopher_id);
}
}
int main() {
pthread_t philosopher_threads[NUM_PHILOSOPHERS];
int philosopher_ids[NUM_PHILOSOPHERS];
// Initialize semaphores
sem_init(&mutex, 0, 1);
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_init(&phil_sem[i], 0, 0);
philosopher_ids[i] = i;
}
// Create philosopher threads
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_create(&philosopher_threads[i], NULL, philosopher, (void *)&philosopher_ids[i]);
}
// Join philosopher threads
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
pthread_join(philosopher_threads[i], NULL);
}
// Destroy semaphores
sem_destroy(&mutex);
for (int i = 0; i < NUM_PHILOSOPHERS; i++) {
sem_destroy(&phil_sem[i]);
}
return 0;
}
Q. Write
Program to implement Banker’s algorithm for deadlock avoidance.
#include <stdio.h>
#include <stdbool.h>
#define MAX_PROCESSES 10
#define MAX_RESOURCES 10
int available[MAX_RESOURCES];
int max[MAX_PROCESSES][MAX_RESOURCES];
int allocation[MAX_PROCESSES][MAX_RESOURCES];
int need[MAX_PROCESSES][MAX_RESOURCES];
bool finish[MAX_PROCESSES];
int num_processes, num_resources;
// Function to check if the current state is safe
bool isSafe() {
int work[MAX_RESOURCES];
bool finish_copy[MAX_PROCESSES];
int i, j;
// Initialize work to available resources
for (i = 0; i < num_resources; i++) {
work[i] = available[i];
}
// Initialize finish_copy to finish array
for (i = 0; i < num_processes; i++) {
finish_copy[i] = finish[i];
}
// Check for unfinished processes
int unfinished = num_processes;
while (unfinished > 0) {
bool found = false;
for (i = 0; i < num_processes; i++) {
if (!finish_copy[i]) {
// Check if need can be satisfied with available resources
bool canBeSatisfied = true;
for (j = 0; j < num_resources; j++) {
if (need[i][j] > work[j]) {
canBeSatisfied = false;
break;
}
}
// If need can be satisfied, mark the process as finished and release allocated resources
if (canBeSatisfied) {
finish_copy[i] = true;
for (j = 0; j < num_resources; j++) {
work[j] += allocation[i][j];
}
found = true;
unfinished--;
}
}
}
// If no process can be executed, the current state is unsafe
if (!found) {
return false;
}
}
return true;
}
// Function to request resources by a process
void requestResources(int process_id, int request[]) {
int i;
// Check if the request can be granted
for (i = 0; i < num_resources; i++) {
if (request[i] > need[process_id][i] || request[i] > available[i]) {
printf("Process %d's request cannot be granted.\n", process_id);
return;
}
}
// Try to allocate resources
for (i = 0; i < num_resources; i++) {
available[i] -= request[i];
allocation[process_id][i] += request[i];
need[process_id][i] -= request[i];
}
// Check if the current state is safe
if (isSafe()) {
printf("Process %d's request is granted.\n", process_id);
} else {
// If the current state is not safe, rollback the allocation
for (i = 0; i < num_resources; i++) {
available[i] += request[i];
allocation[process_id][i] -= request[i];
need[process_id][i] += request[i];
}
printf("Process %d's request cannot be granted.\n", process_id);
}
}
int main() {
int i, j;
int request[MAX_RESOURCES];
int process_id;
// Input the number of processes and resources
printf("Enter the number of processes: ");
scanf("%d", &num_processes);
printf("Enter the number of resources: ");
scanf("%d", &num_resources);
// Input the available resources
printf("Enter the available resources: ");
for (i = 0; i < num_resources; i++) {
scanf("%d", &available[i]);
}
// Input the maximum resource allocation for each process
printf("Enter the maximum resource allocation for each process:\n");
for (i = 0; i < num_processes; i++) {
printf("For process %d: ", i);
for (j = 0; j < num_resources; j++) {
scanf("%d", &max[i][j]);
need[i][j] = max[i][j];
}
finish[i] = false;
}
// Input the current resource allocation for each process
printf("Enter the current resource allocation for each process:\n");
for (i = 0; i < num_processes; i++) {
printf("For process %d: ", i);
for (j = 0; j < num_resources; j++) {
scanf("%d", &allocation[i][j]);
need[i][j] -= allocation[i][j];
}
}
// Input the process ID and resource request
printf("Enter the process ID making the request: ");
scanf("%d", &process_id);
printf("Enter the resource request: ");
for (i = 0; i < num_resources; i++) {
scanf("%d", &request[i]);
}
// Process the resource request
requestResources(process_id, request);
return 0;
}
Q. Write Program to implement different memory management
techniques
#include <stdio.h>
#include <stdlib.h>
// Define a block of memory with a fixed size
#define MEMORY_SIZE 1000
char memory[MEMORY_SIZE];
// Linked list node to represent a memory block
typedef struct Node {
int size;
int start;
struct Node* next;
} Node;
Node* head = NULL; // Head of the free memory block linked list
// Function to initialize the memory allocator
void initialize() {
head = (Node*)malloc(sizeof(Node));
head->size = MEMORY_SIZE;
head->start = 0;
head->next = NULL;
}
// Function to allocate memory using first-fit approach
void* allocate(int size) {
Node* current = head;
Node* prev = NULL;
while (current != NULL) {
if (current->size >= size) {
// Allocate memory from this block
void* ptr = &memory[current->start];
if (current->size == size) {
// If the block size exactly matches, remove the block from the list
if (prev != NULL) {
prev->next = current->next;
} else {
head = current->next;
}
free(current);
} else {
// Update the block's size and start address
current->size -= size;
current->start += size;
}
return ptr;
}
prev = current;
current = current->next;
}
// No suitable block found
return NULL;
}
// Function to free memory
void deallocate(void* ptr, int size) {
Node* current = head;
Node* prev = NULL;
// Find the position to insert the freed block in the list
while (current != NULL && current->start < (ptr - &memory[0])) {
prev = current;
current = current->next;
}
// Create a new block for the freed memory
Node* new_block = (Node*)malloc(sizeof(Node));
new_block->size = size;
new_block->start = ptr - &memory[0];
// Insert the new block into the list
if (prev != NULL) {
new_block->next = prev->next;
prev->next = new_block;
} else {
new_block->next = head;
head = new_block;
}
// Merge adjacent blocks if possible
if (new_block->next != NULL && new_block->start + new_block->size == new_block->next->start) {
new_block->size += new_block->next->size;
Node* temp = new_block->next;
new_block->next = new_block->next->next;
free(temp);
}
if (prev != NULL && prev->start + prev->size == new_block->start) {
prev->size += new_block->size;
prev->next = new_block->next;
free(new_block);
}
}
// Function to display the memory blocks
void displayMemory() {
Node* current = head;
while (current != NULL) {
printf("Start: %d, Size: %d\n", current->start, current->size);
current = current->next;
}
}
int main() {
initialize();
// Allocate memory blocks
void* block1 = allocate(100);
void* block2 = allocate(200);
void* block3 = allocate(150);
printf("Allocated blocks:\n");
displayMemory();
// Free a memory block
deallocate(block2, 200);
printf("\nAfter freeing a block:\n");
displayMemory();
// Allocate a new memory block after freeing the previous one
void* block4 = allocate(300);
printf("\nAllocated blocks after allocating a new one:\n");
displayMemory();
return 0;
}
Q. Write Program to implement
sequential and indexed file allocation methods.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_BLOCKS 100
#define MAX_FILES 10
// Structure to represent a block
struct Block {
int block_id;
bool allocated;
};
// Structure to represent a file
struct File {
int file_id;
int num_blocks;
int block_ids[MAX_BLOCKS];
};
// Global array to represent blocks
struct Block blocks[MAX_BLOCKS];
// Function to initialize blocks
void initializeBlocks() {
for (int i = 0; i < MAX_BLOCKS; i++) {
blocks[i].block_id = i;
blocks[i].allocated = false;
}
}
// Function to allocate blocks for a file using sequential allocation
bool sequentialAllocation(struct File *file) {
int start_block = -1;
int count = 0;
// Find consecutive free blocks
for (int i = 0; i < MAX_BLOCKS; i++) {
if (!blocks[i].allocated) {
if (start_block == -1) {
start_block = i;
}
count++;
if (count == file->num_blocks) {
break;
}
} else {
start_block = -1;
count = 0;
}
}
// If enough free blocks are found, allocate them
if (start_block != -1 && count == file->num_blocks) {
for (int i = start_block; i < start_block + file->num_blocks; i++) {
blocks[i].allocated = true;
file->block_ids[i - start_block] = i;
}
return true;
} else {
printf("Error: Not enough free blocks for sequential allocation.\n");
return false;
}
}
// Function to allocate blocks for a file using indexed allocation
bool indexedAllocation(struct File *file) {
int index_block = -1;
// Find a free block for the index block
for (int i = 0; i < MAX_BLOCKS; i++) {
if (!blocks[i].allocated) {
index_block = i;
break;
}
}
// If free block is found, allocate index block and allocate data blocks
if (index_block != -1) {
blocks[index_block].allocated = true;
file->block_ids[0] = index_block;
// Allocate data blocks using index block
for (int i = 1; i <= file->num_blocks; i++) {
int data_block = -1;
for (int j = 0; j < MAX_BLOCKS; j++) {
if (!blocks[j].allocated) {
data_block = j;
break;
}
}
if (data_block == -1) {
printf("Error: Not enough free blocks for indexed allocation.\n");
return false;
}
blocks[data_block].allocated = true;
blocks[index_block].block_id = data_block;
file->block_ids[i] = data_block;
}
return true;
} else {
printf("Error: Not enough free blocks for indexed allocation.\n");
return false;
}
}
// Function to deallocate blocks allocated for a file
void deallocateBlocks(struct File *file) {
for (int i = 0; i < file->num_blocks; i++) {
blocks[file->block_ids[i]].allocated = false;
}
}
int main() {
// Initialize blocks
initializeBlocks();
// Example files
struct File files[MAX_FILES] = {
{0, 3, {0, 0, 0}},
{1, 5, {0, 0, 0, 0, 0}},
{2, 2, {0, 0}},
{3, 4, {0, 0, 0, 0}}
};
// Allocate blocks for each file using sequential allocation
printf("Sequential Allocation:\n");
for (int i = 0; i < MAX_FILES; i++) {
printf("Allocating blocks for File %d...\n", files[i].file_id);
if (sequentialAllocation(&files[i])) {
printf("Blocks allocated successfully.\n");
} else {
printf("Failed to allocate blocks.\n");
}
}
// Deallocate blocks for each file
printf("\nDeallocating blocks...\n");
for (int i = 0; i < MAX_FILES; i++) {
printf("Deallocating blocks for File %d...\n", files[i].file_id);
deallocateBlocks(&files[i]);
printf("Blocks deallocated successfully.\n");
}