0% found this document useful (0 votes)
20 views22 pages

Bhaktapur Multiple Campus: Tribhuvan University

This document is a practical lab report for an Operating System course at Tribhuvan University, detailing various lab exercises. It includes commands for directory and file management, C programming examples for process creation, scheduling algorithms, and thread synchronization using semaphores. The report is submitted by Biplav Ghimire and includes source code for multiple scheduling algorithms such as FCFS, SJF, SRTF, and Priority Scheduling.

Uploaded by

BIPLAV Ghimire
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views22 pages

Bhaktapur Multiple Campus: Tribhuvan University

This document is a practical lab report for an Operating System course at Tribhuvan University, detailing various lab exercises. It includes commands for directory and file management, C programming examples for process creation, scheduling algorithms, and thread synchronization using semaphores. The report is submitted by Biplav Ghimire and includes source code for multiple scheduling algorithms such as FCFS, SJF, SRTF, and Priority Scheduling.

Uploaded by

BIPLAV Ghimire
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 22

TRIBHUVAN UNIVERSITY

BHAKTAPUR MULTIPLE CAMPUS


DUDHPATI, BHAKTAPUR

A PRACTICAL LAB REPORT


OF
Operating System
Submitted By:
Biplav Ghimire
Symbol : 12024 / 20

Submitted To:
Karan Qode

Bhaktapur Multiple Campus

Date of Submission: 2079/07/24


LAB-1
1. Create a directory named lab1 and navigate into it.
This command creates a new directory and moves into it.
mkdir lab1
cd lab1

2. Create an empty file named demo.txt and display its path.


The 'touch' command creates an empty file, and 'real path' shows its full path.
type nul > demo.txt
for %i in (demo.txt) do @echo %~fi

3. List all files and directories, including hidden ones.


Dir /a:h
4. Copy a file named file1.txt to a folder named backup.
This command copies file1.txt into the backup folder.
copy demo.txt oknice/

5. Move a file named notes.txt to the parent directory.


move demo.txt ..

6. Rename a file oldname.txt to newname.txt.


rename demo77.txt demo123.txt

7. Delete a file named temp.txt.


Deletes the specified file.
8. Remove a directory named testdir.
Rmdir testdir

9. Display the contents of a file named data.txt.


Type demo.txt

10. Show the current working directory.


Displays the current directory path.

11. Display the current date and time.


Shows the system's current date and time.
12. Show all currently running processes.
Displays all active system processes in detail.
tasklist
LAB-2
1. Program to Create a Child Process using fork ().
This C program demonstrates how to use the fork() system call to create a child
process. The child process prints 'Child Process' and its PID, while the parent prints
'Parent Process' and its PID.
Source Code:
#include <stdio.h>
#include <unistd.h>

int main() {
pid_t pid = fork();

if (pid == 0) {
printf("Child Process\n");
printf("Child PID: %d\n", getpid());
} else if (pid > 0) {
printf("Parent Process\n");
printf("Parent PID: %d\n", getpid());
} else {
printf("Fork failed\n");
}

return 0;
}
2. Program Using pthreads to Create 2 Threads
This C program uses pthreads to create two threads that run concurrently. Each thread
prints a separate message. pthread_create() is used to create the threads, and
pthread_join() ensures the main function waits for both threads to finish.
Source Code:
#include <stdio.h>
#include <pthread.h>

void* threadFunc1(void* arg) {


printf("Thread 1: Hello\n");
return NULL;
}

void* threadFunc2(void* arg) {


printf("Thread 2: World\n");
return NULL;
}

int main() {
pthread_t t1, t2;

pthread_create(&t1, NULL, threadFunc1, NULL);


pthread_create(&t2, NULL, threadFunc2, NULL);

pthread_join(t1, NULL);
pthread_join(t2, NULL);

return 0;
}
LAB-3
1. Write a program in C to simulate First-Come First-Served (FCFS) scheduling
algorithm.
FCFS is the simplest scheduling algorithm where processes are executed in the order
they arrive. It's non-preemptive, meaning once a process starts, it runs to completion.
While easy to implement, it can lead to long waiting times for short processes if they
arrive after long ones.
Source code:
#include <stdio.h>
void calculateTimes(int processes[], int n, int bt[], int wt[], int tat[]) {
wt[0] = 0;
for (int i = 1; i < n; i++)
wt[i] = bt[i-1] + wt[i-1];
for (int i = 0; i < n; i++)
tat[i] = bt[i] + wt[i];
}
int main() {
int processes[] = {1, 2, 3};
int n = sizeof processes / sizeof processes[0];
int burst_time[] = {10, 5, 8};
int wt[n], tat[n];
calculateTimes(processes, n, burst_time, wt, tat);
printf("Process\tBT\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\n", processes[i], burst_time[i], wt[i], tat[i]);
return 0;
}
2. Write a program in C to simulate Shortest Job First (SJF) non-preemptive
scheduling algorithm.
SJF non-preemptive selects the process with the smallest burst time from the ready
queue. Once started, it runs to completion. This algorithm minimizes average waiting
time but requires knowing burst times in advance, which is often impractical.
Source code:
#include <stdio.h>
#include <stdbool.h>

struct Process {
int pid, bt, wt, tat;
};

void sjf(struct Process p[], int n) {


for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (p[j].bt > p[j+1].bt) {
struct Process temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}

p[0].wt = 0;
for (int i = 1; i < n; i++) {
p[i].wt = p[i-1].bt + p[i-1].wt;
p[i].tat = p[i].wt + p[i].bt;
}
p[0].tat = p[0].bt;
}

int main() {
struct Process p[] = {{1, 6}, {2, 8}, {3, 7}, {4, 3}};
int n = sizeof(p)/sizeof(p[0]);
sjf(p, n);

printf("Process\tBT\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\n", p[i].pid, p[i].bt, p[i].wt, p[i].tat);

return 0;
}
3. Write a program in C to simulate Shortest Remaining Time First (SRTF)
preemptive scheduling algorithm.
SRTF is the preemptive version of SJF. The scheduler always chooses the process
with the shortest remaining time. If a new process arrives with shorter burst time, the
current process is preempted. This provides better response times than SJF.
Source Code:
#include <stdio.h>
#include <stdbool.h>

struct Process {
int pid, at, bt, rt, wt, tat, ct;
};

void srtf(struct Process p[], int n) {


int complete = 0, t = 0, min_rt = 9999, shortest = -1;
bool check = false;

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


p[i].rt = p[i].bt;

while (complete != n) {
for (int j = 0; j < n; j++) {
if (p[j].at <= t && p[j].rt < min_rt && p[j].rt > 0) {
min_rt = p[j].rt;
shortest = j;
check = true;
}
}

if (!check) { t++; continue; }

p[shortest].rt--;
min_rt = p[shortest].rt;
if (min_rt == 0) {
min_rt = 9999;
complete++;
check = false;
p[shortest].ct = t + 1;
p[shortest].tat = p[shortest].ct - p[shortest].at;
p[shortest].wt = p[shortest].tat - p[shortest].bt;
}
t++;
}
}

int main() {
struct Process p[] = {{1, 0, 8}, {2, 1, 4}, {3, 2, 9}, {4, 3, 5}};
int n = sizeof(p)/sizeof(p[0]);

srtf(p, n);

printf("Process\tAT\tBT\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\t%d\n", p[i].pid, p[i].at, p[i].bt, p[i].wt, p[i].tat);

return 0;
}
4. Write a program in C to simulate Priority Scheduling (non-preemptive)
algorithm.
Non-preemptive priority scheduling executes processes based on their priority. The
highest priority process runs to completion before the next is selected. Lower numbers
typically indicate higher priority. Starvation of low-priority processes can occur.
Source Code:
#include <stdio.h>

struct Process {
int pid, bt, priority, wt, tat;
};

void prioritySchedule(struct Process p[], int n) {


for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (p[j].priority > p[j+1].priority) {
struct Process temp = p[j];
p[j] = p[j+1];
p[j+1] = temp;
}

p[0].wt = 0;
for (int i = 1; i < n; i++) {
p[i].wt = p[i-1].bt + p[i-1].wt;
p[i].tat = p[i].wt + p[i].bt;
}
p[0].tat = p[0].bt;
}

int main() {
struct Process p[] = {{1, 10, 3}, {2, 5, 1}, {3, 8, 2}};
int n = sizeof(p)/sizeof(p[0]);

prioritySchedule(p, n);
printf("Process\tBT\tPriority\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t\t%d\t%d\n", p[i].pid, p[i].bt, p[i].priority, p[i].wt, p[i].tat);

return 0;
}
5. Write a program in C to simulate Priority Scheduling (preemptive)
algorithm.
Preemptive priority scheduling allows higher priority processes to interrupt currently
running lower priority ones. This provides better response for high-priority processes
but increases context switching overhead and can cause starvation.

Source Code:
#include <stdio.h>
#include <stdbool.h>

struct Process {
int pid, at, bt, priority, rt, wt, tat, ct;
};

void preemptivePriority(struct Process p[], int n) {


int complete = 0, t = 0, highest = -1, min_priority = 9999;
bool check = false;

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


p[i].rt = p[i].bt;

while (complete != n) {
for (int j = 0; j < n; j++) {
if (p[j].at <= t && p[j].priority < min_priority && p[j].rt > 0) {
min_priority = p[j].priority;
highest = j;
check = true;
}
}

if (!check) { t++; continue; }

p[highest].rt--;
min_priority = p[highest].priority;
if (p[highest].rt == 0) {
min_priority = 9999;
complete++;
check = false;
p[highest].ct = t + 1;
p[highest].tat = p[highest].ct - p[highest].at;
p[highest].wt = p[highest].tat - p[highest].bt;
}
t++;
}
}

int main() {
struct Process p[] = {{1, 0, 4, 2}, {2, 1, 3, 1}, {3, 2, 5, 3}};
int n = sizeof(p)/sizeof(p[0]);

preemptivePriority(p, n);

printf("Process\tAT\tBT\tPriority\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\t\t%d\t%d\n", p[i].pid, p[i].at, p[i].bt, p[i].priority,
p[i].wt, p[i].tat);

return 0;
}
6. Write a program in C to simulate Round Robin (RR) scheduling algorithm
using a given time quantum.
Round Robin assigns a fixed time quantum to each process in cyclic order. If a
process does not complete within its quantum, it's preempted and moved to the back
of the queue. This provides fair CPU allocation but performance depends heavily on
quantum size.
Source Code:
#include <stdio.h>
#include <stdbool.h>

struct Process {
int pid, at, bt, rt, wt, tat;
};

void roundRobin(struct Process p[], int n, int quantum) {


int t = 0, remaining = n;

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


p[i].rt = p[i].bt;

while (remaining > 0) {


for (int i = 0; i < n; i++) {
if (p[i].rt > 0 && p[i].at <= t) {
if (p[i].rt > quantum) {
t += quantum;
p[i].rt -= quantum;
} else {
t += p[i].rt;
p[i].rt = 0;
remaining--;
p[i].tat = t - p[i].at;
p[i].wt = p[i].tat - p[i].bt;
}
}
}
}
}

int main() {
struct Process p[] = {{1, 0, 5}, {2, 1, 3}, {3, 2, 8}};
int n = sizeof(p)/sizeof(p[0]);
int quantum = 2;

roundRobin(p, n, quantum);

printf("Process\tAT\tBT\tWT\tTAT\n");
for (int i = 0; i < n; i++)
printf("%d\t%d\t%d\t%d\t%d\n", p[i].pid, p[i].at, p[i].bt, p[i].wt, p[i].tat);

return 0;
}
LAB-4
1. Write a program to implement a semaphore to synchronize two threads where
one thread prints "Hello" and the other prints "World".
Semaphores are synchronization primitives used to control access to shared resources
in a multi-threaded environment. They help prevent race conditions and ensure
orderly execution of threads.
In this program, we use two semaphores to synchronize two threads:
Thread 1 prints "Hello"
Thread 2 prints "World"
The goal is to ensure that "Hello" is always printed before "World", demonstrating
thread synchronization.
Key Components:
Semaphores (sem_hello and sem_world)
sem_hello is initialized to 1 (available), allowing the first thread to run immediately.
sem_world is initialized to 0 (blocked), forcing the second thread to wait.
Thread Functions:
print_hello thread:
Waits on sem_hello (initially available).
Prints "Hello ".
Signals sem_world to allow the second thread to proceed.
print_world thread:
Waits on sem_world (initially blocked until signaled).
Prints "World\n".
Signals sem_hello (for potential reuse in extended scenarios).
Main Function Workflow:
Initializes semaphores.
Creates two threads (t1 for print_hello, t2 for print_world).
Waits for both threads to finish (pthread_join).
Destroys semaphores to free resources.

Source Code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

sem_t sem_hello, sem_world;

void* print_hello(void* arg) {


sem_wait(&sem_hello); // Wait for hello semaphore
printf("Hello ");
sem_post(&sem_world); // Signal world semaphore
return NULL;
}

void* print_world(void* arg) {


sem_wait(&sem_world); // Wait for world semaphore
printf("World\n");
sem_post(&sem_hello); // Signal hello semaphore (for potential reuse)
return NULL;
}

int main() {
pthread_t t1, t2;

// Initialize semaphores
sem_init(&sem_hello, 0, 1); // Hello starts available
sem_init(&sem_world, 0, 0); // World starts blocked

// Create threads
pthread_create(&t1, NULL, print_hello, NULL);
pthread_create(&t2, NULL, print_world, NULL);

// Wait for threads to finish


pthread_join(t1, NULL);
pthread_join(t2, NULL);

// Cleanup semaphores
sem_destroy(&sem_hello);
sem_destroy(&sem_world);

return 0;
}

You might also like