Operating System - Ass
Operating System - Ass
Operating System - Ass
Parveen Kumar
2022ucp1577
Assignment - 1
ifstream inputFile("input.txt");
while(getline(inputFile,text)){
wholetext += text;
}
to_AsciiValue(wholetext);
inputFile.close();
return 0;
}
vector<int>arr;
int j = 0;
while(ascii != 0){
j = ascii%16;
arr.push_back(j);
ascii = ascii/16;
}
reverse(arr.begin(),arr.end());
v.push_back(arr);
}
for(auto i: v){
for(auto j: i){
outputFile<<j;
}
outputFile<<” “;
}
outputFile.close();
}
Int main(){
String text;
string wholetext = “”;
ifstream inputFile(“input.txt”);
while(getline(inputFile,text)){
wholetext += text;
}
to_HexValue(wholetext);
inputFile.close();
return 0;
}
Assignment - 2
Process API and system Calls
4. Execution Paths:
After fork() is called, both the parent and child processes
continue
executing from the point where fork() was called.
However, they can take
different execution paths based on the return value of
fork().
Code :
#include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 int main(int argc, char *argv[]) {
6 printf("hello (pid:%d)\n", (int) getpid());
7 int rc = fork();
8 if (rc < 0) {
9 // fork failed
10 fprintf(stderr, "fork failed\n");
11 exit(1);
12 } else if (rc == 0) {
13 // child (new process)
14 printf("child (pid:%d)\n", (int) getpid());
15 } else {
16 // parent goes down this path (main)
17 printf("parent of %d (pid:%d)\n",
18 rc, (int) getpid());
19 }
20 return 0;
21 }
Output:
➜ ./p1
hello world (pid:8048)
value of rc: 8049
hello, I am parent of 8049 (pid:8048)
value of rc: 0
hello, I am child (pid:8049)
…………………………………………………………………
……………………………………
(ii) P2.c
The fork() system call is used to create a new process,
and wait() is used by the parent
process to wait for the child process to finish execution.
Here's a detailed explanation of
how these system calls work together:
1. Initial Execution: The program starts execution from
the main() function, and the
process running this program is assigned a unique
process identifier (PID).
Code:
#include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/wait.h>
5
6 int main(int argc, char *argv[]) {
7 printf("hello (pid:%d)\n", (int) getpid());
8 int rc = fork();
9 if (rc < 0) { // fork failed; exit
10 fprintf(stderr, "fork failed\n");
11 exit(1);
12 } else if (rc == 0) { // child (new process)
13 printf("child (pid:%d)\n", (int) getpid());
14 } else { // parent goes down this path
15 int rc_wait = wait(NULL);
16 printf("parent of %d (rc_wait:%d) (pid:%d)\n",
17 rc, rc_wait, (int) getpid());
18 }
19 return 0;
20 }
Output:
➜ ./p2
hello world (pid:8057)
value of rc: 8058
value of rc: 0
hello, I am child (pid:8058)
hello, I am parent of 8058 (wc:8058) (pid:8057)
…………………………………………………………………
………………………………….
(iii) P3.c
In this section, we will explore the exec() system call,
which is used to run a
different program from within a child process created by
fork(). This allows the
child process to replace its entire memory space with a
new program.
The fork() system call is used to create a new process
(the child), and the wait()
system call is used by the parent process to wait for the
child process to finish.
The exec() system call is then used by the child process
to replace its memory
space with a new program. This combination is powerful
and commonly used in
UNIX-like operating systems.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
int
main(int argc, char *argv[])
{
printf("hello world (pid:%d)\n", (int) getpid());
int rc = fork();
if (rc < 0) {
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) {
// child (new process)
printf("hello, I am child (pid:%d)\n", (int)
getpid());
char *myargs[3];
myargs[0] = strdup("wc"); // program:
"wc" (word count)
myargs[1] = strdup("p3.c"); // argument: file
to count
myargs[2] = NULL; // marks end of array
execvp(myargs[0], myargs); // runs word count
printf("this shouldn't print out");
} else {
// parent goes down this path (original process)
int wc = wait(NULL);
printf("hello, I am parent of %d (wc:%d)
(pid:%d)\n",
rc, wc, (int) getpid());
}
return 0;
}
➜ ./p3
hello world (pid:8064)
value of rc: 8065
value of rc: 0
hello, I am child (pid:8065)
34 130 1020 p3.c
hello, I am parent of 8065 (wc:8065) (pid:8064)
…………………………………………………………………
…………………………………..
(iv) p4.c
we extend the process creation and management API to
include output
redirection. We use the fork() system call to create a
new process (child),
the wait() system call to wait for the child process to
complete, and the
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/wait.h>
int
main(int argc, char *argv[])
{
int rc = fork();
if (rc < 0) {
// fork failed; exit
fprintf(stderr, "fork failed\n");
exit(1);
} else if (rc == 0) {
// child: redirect standard output to a file
close(STDOUT_FILENO);
open("./p4.output",
O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
Output:
➜ ./p4
value of rc: 8074
value of rc: 0
Assignment - 3
CPU Scheduling using file handling and printing
statues of processes at all time.
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <string>
#include <sstream>
#include <map>
using namespace std;
struct Process {
int id, priority, arrivalTime;
vector<int> bursts; // CPU and IO bursts
int burstIndex = 0, remainingTime, startTime = -1,
completionTime = -1;
string history = "";
};
void readProcessesFromFile(vector<Process>&
processes, const string& filename) {
ifstream file(filename);
string line;
getline(file, line);
int n = stoi(line);
for (int i = 0; i < n; ++i) {
getline(file, line);
stringstream ss(line);
string token;
Process proc;
getline(ss, token, ','); proc.id = stoi(token);
getline(ss, token, ','); proc.priority = stoi(token);
getline(ss, token, ','); proc.arrivalTime = stoi(token);
while (getline(ss, token, ',')) {
int burst = stoi(token);
if (burst == -1) break;
proc.bursts.push_back(burst);
}
proc.remainingTime = proc.bursts[0];
processes.push_back(proc);
}
file.close();
}
void printProcessHistory(const vector<Process>&
processes) {
for (const auto& proc : processes) {
cout << "Process " << proc.id << ": " << proc.history <<
endl;
}
}
void fcfs(vector<Process> processes) {
queue<Process*> readyQueue;
int time = 0;
while (!processes.empty() || !readyQueue.empty()) {
for (auto it = processes.begin(); it != processes.end();) {
if (it->arrivalTime <= time) {
readyQueue.push(&(*it));
it = processes.erase(it);
} else {
++it;
}
}
if (!readyQueue.empty()) {
Process* proc = readyQueue.front();
readyQueue.pop();
while (proc->burstIndex < proc->bursts.size()) {
for (int t = 0; t < proc->bursts[proc->burstIndex]; ++t) {
proc->history += 'C';
++time;
}
proc->burstIndex++;
if (proc->burstIndex < proc->bursts.size()) {
for (int t = 0; t < proc->bursts[proc->burstIndex]; ++t) {
proc->history += 'R';
++time;
}
proc->burstIndex++;
}
}
proc->completionTime = time;
} else {
++time;
}
}
printProcessHistory(processes);
}
void sjf(vector<Process> processes) {
auto cmp = [](Process* a, Process* b) {
return a->remainingTime > b->remainingTime;
};
priority_queue<Process*, vector<Process*>,
decltype(cmp)> readyQueue(cmp);
int time = 0;
while (!processes.empty() || !readyQueue.empty()) {
for (auto it = processes.begin(); it != processes.end();) {
if (it->arrivalTime <= time) {
readyQueue.push(&(*it));
it = processes.erase(it);
} else {
++it;
}
}
if (!readyQueue.empty()) {
Process* proc = readyQueue.top();
readyQueue.pop();
while (proc->burstIndex < proc->bursts.size()) {
proc->history += 'C';
++time;
proc->remainingTime--;
if (proc->remainingTime == 0) {
proc->burstIndex += 2;
if (proc->burstIndex < proc->bursts.size()) {
proc->remainingTime = proc->bursts[proc->burstIndex];
}
break;
}
}
if (proc->remainingTime > 0) {
readyQueue.push(proc);
} else {
proc->completionTime = time;
}
} else {
++time;
}
}
printProcessHistory(processes);
}
void priorityScheduling(vector<Process> processes) {
auto cmp = [](Process* a, Process* b) {
return a->priority > b->priority;
};
priority_queue<Process*, vector<Process*>,
decltype(cmp)> readyQueue(cmp);
int time = 0;
while (!processes.empty() || !readyQueue.empty()) {
for (auto it = processes.begin(); it != processes.end();) {
if (it->arrivalTime <= time) {
readyQueue.push(&(*it));
it = processes.erase(it);
} else {
++it;
}
}
if (!readyQueue.empty()) {
Process* proc = readyQueue.top();
readyQueue.pop();
while (proc->burstIndex < proc->bursts.size()) {
proc->history += 'C';
++time;
proc->remainingTime--;
if (proc->remainingTime == 0) {
proc->burstIndex += 2;
if (proc->burstIndex < proc->bursts.size()) {
proc->remainingTime = proc->bursts[proc->burstIndex];
}
break;
}
}
if (proc->remainingTime > 0) {
readyQueue.push(proc);
} else {
proc->completionTime = time;
}
} else {
++time;
}
}
printProcessHistory(processes);
}
void roundRobin(vector<Process> processes, int
quantum) {
queue<Process*> readyQueue;
int time = 0;
while (!processes.empty() || !readyQueue.empty()) {
for (auto it = processes.begin(); it != processes.end();) {
if (it->arrivalTime <= time) {
readyQueue.push(&(*it));
it = processes.erase(it);
} else {
++it;
}
}
if (!readyQueue.empty()) {
Process* proc = readyQueue.front();
readyQueue.pop();
int slice = min(quantum, proc->remainingTime);
for (int t = 0; t < slice; ++t) {
proc->history += 'C';
++time;
}
proc->remainingTime -= slice;
if (proc->remainingTime == 0) {
proc->burstIndex += 2;
if (proc->burstIndex < proc->bursts.size()) {
proc->remainingTime = proc->bursts[proc->burstIndex];
} else {
proc->completionTime = time;
}
}
if (proc->remainingTime > 0) {
readyQueue.push(proc);
}
} else {
++time;
}
}
printProcessHistory(processes);
}
int main() {
vector<Process> processes;
readProcessesFromFile(processes, "proc.dat");
int choice;
cout << "Choose Scheduling Algorithm:\n";
cout << "1. FCFS\n2. SJF (Preemptive)\n3. Priority
(Preemptive)\n4. Round Robin\n";
cin >> choice;
switch (choice) {
case 1: fcfs(processes); break;
case 2: sjf(processes); break;