OS Project
OS Project
Operating System
Prepared By
Name ID section
MOTI HATEW ATR/3469/10 3
Henok Adane ATR/3109/10 3
Hawltu Yenealem ATR/9258/10 1
Natnael Awol ATR/3701/09 1
February, 2021
Page |2
Scheduling Algorithm 2
Chat Room 19
Dining philosophy 28
Scheduling Algorithm
Contents
Introduction/Purpose........................................................................................................3
Methods/Procedure...........................................................................................................6
Priority code……………………………………………………………………………...............9
Output...............................................................................................................................3
Conclusion…………………………………………………………………………….................16
References.........................................................................................................................16
2
Page |3
Introduction/Purpose
CPU Scheduling is a process of determining which process will own CPU for execution while
another process is on hold. The main task of CPU scheduling is to make sure that whenever
the CPU remains idle, the OS at least select one of the processes available in the ready queue
for execution. The selection process will be carried out by the CPU scheduler. It selects one of
the processes in memory that are ready for execution.
1. Preemptive Scheduling
In Preemptive Scheduling, the tasks are mostly assigned with their priorities. Sometimes it is
important to run a task with a higher priority before another lower priority task, even if the
lower priority task is still running. The lower priority task holds for some time and resumes
when the higher priority task finishes its execution.
2. Non-Preemptive Scheduling
In this type of scheduling method, the CPU has been allocated to a specific process. The
process that keeps the CPU busy will release the CPU either by switching context or
terminating. It is the only method that can be used for various hardware platforms. That's
because it doesn't need special hardware (for example, a timer) like preemptive scheduling.
Shortest Job First (SJF): Process which have the shortest burst time
are scheduled first. If two processes have the same bust time then FCFS is
used to break the tie. It is a non-preemptive scheduling algorithm.
4
Page |5
Materials/Components and
Equipment
➢ Java IDLE
➢ Java: JDK
Procedures
import java.util.List;
void run() {
List<Process> processes = getInput();
System.out.println("Order in which processes gets executed \n");
for (int i = 0; i < processes.size(); i++)
System.out.print(processes.get(i).processID + " ");
findavgTime(processes, processes.size());
}
}
import java.util.Collections;
import java.util.List;
5
Page |6
// which checks for the processes arrival time if all comes at once
boolean checkSameArrival(List<Process> proc) {
boolean isSame = false;
for (int i = 0; i < proc.size(); i++) {
if (proc.get(i).arrivalTime == 0) {
isSame = true;
} else {
isSame = false;
}
}
return isSame;
}
void run() {
List<Process> processes = sortProcesses(getInput());
System.out.println("Order in which processes gets executed \n");
for (int i = 0; i < processes.size(); i++) {
System.out.print(processes.get(i).processID + " ");
}
findavgTime(processes, processes.size());
}
}
import java.util.List;
6
Page |7
@Override
void findWaitingTime(List<Process> proc, int n, int wt[]) {
int rem_time[] = new int[n];
while (complete != n) {
for (int j = 0; j < n; j++) {
if ((proc.get(j).arrivalTime <= clock_time) && (rem_time[j] <
minm) && rem_time[j] > 0) {
minm = rem_time[j];
sj = j;
check = true;
}
}
if (!check) {
clock_time++;
continue;
}
rem_time[sj]--;
// Update minimum
minm = rem_time[sj];
if (minm == 0)
minm = Integer.MAX_VALUE;
if (rem_time[sj] == 0) {
complete++;
check = false;
finish_time = clock_time + 1;
wt[sj] = finish_time - proc.get(sj).burstTime -
proc.get(sj).arrivalTime;
if (wt[sj] < 0) {
wt[sj] = 0;
}
}
clock_time++;
}
}
void run() {
List<Process> processes = getInput();
System.out.println("Order in which processes gets executed \n");
for (int i = 0; i < processes.size(); i++)
System.out.print(processes.get(i).processID + " ");
findavgTime(processes, processes.size());
}
}
7
Page |8
4. Priority Scheduling
package com.company;
import java.util.List;
void run() {
List<Process> processes = getInput();
processes.sort(new Process.PriorityComparator());
System.out.println("Order in which processes gets executed ");
for (int i = 0; i < processes.size(); i++)
System.out.print(processes.get(i).processID + " ");
findavgTime(processes, processes.size());
}
}
import java.util.List;
import java.util.Scanner;
// @Override
void findWaitingTime(List<Process> proc, int n, int quantum, int
completion_time[]) {
int rem_time[] = new int[n];
for (int i = 0; i < n; i++) {
rem_time[i] = proc.get(i).burstTime;
}
int t = 0;
int clock_counter = 0;
while (true) {
boolean done = true;
for (int i = 0; i < n; i++) {
if (rem_time[i] > 0) {
done = false;
if (rem_time[i] > quantum && proc.get(i).arrivalTime <=
clock_counter) {
8
Page |9
t += quantum;
rem_time[i] -= quantum;
clock_counter++;
} else {
if (proc.get(i).arrivalTime <= clock_counter) {
t += rem_time[i];
rem_time[i] = 0;
completion_time[i] = t;
clock_counter++;
}
}
}
}
if (done) {
break;
}
}
}
@Override
void findTurnAroundTime(List<Process> proc, int n, int wt[], int tat[], int
completion_time[]) {
for (int i = 0; i < n; i++) {
tat[i] = completion_time[i] - proc.get(i).arrivalTime;
wt[i] = tat[i] - proc.get(i).burstTime;
}
}
void run() {
Scanner sc = new Scanner(System.in);
int quantum;
System.out.println("Enter Quantum Number: ");
quantum = checkValidInputAndGetValue(sc);
List<Process> processes = getInput();
9
P a g e | 10
6. Scheduling algorithm
package com.company;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
// parent class for all scheduling algorithm that share same process
public class SchedulingAlgorithms {
public String algoType;
public String InputText;
void display(List<Process> proc, int n, int wt[], int tat[], int total_wt,
int total_tat, int compl_time[]) {
System.out.println("\n");
System.out.println("===========================================================
=================================================== ");
System.out.println("Processes ID\t" + InputText + "\t " + "Burst
time\t" + "Waiting time\t" + "Turn Around Time\t" + "completion time\t");
10
P a g e | 11
System.out.println("===========================================================
=================================================== ");
// find waiting time and turnaround time for each process and also total
void findavgTime(List<Process> proc, int n) {
int wt[] = new int[n], tat[] = new int[n], compl_time[] = new int[n];
int total_wt = 0, total_tat = 0;
findWaitingTime(proc, n, wt);
findTurnAroundTime(proc, n, wt, tat, compl_time);
display(proc, n, wt, tat, total_wt, total_tat, compl_time);
}
// get first input
List<Process> getInput() {
Scanner sc = new Scanner(System.in);
System.out.println("Enter Number of Process...");
int numberOfProcess = checkValidInputAndGetValue(sc);
int pId, aT, bT;
List<Process> processes = new ArrayList<>();
for (int i = 0; i < numberOfProcess; i++) {
System.out.println("...Process " + (i + 1) + "...");
System.out.println("Enter Process Id: ");
pId = checkValidInputAndGetValue(sc);
System.out.println("Enter " + InputText + ": ");
aT = checkValidInputAndGetValue(sc);
System.out.println("Enter Burst Time: ");
bT = checkValidInputAndGetValue(sc);
Process process = new Process(pId, bT, aT, algoType);
processes.add(process);
}
return processes;
}
}
11
P a g e | 12
7. Main Class
package com.company;
import java.util.Scanner;
} else if (choice == 2) {
break;
} else {
stop = true;
}
break;
}
case 3: {
PreemptiveSJF preemptiveSJF = new
PreemptiveSJF("PreemptiveSJF");
preemptiveSJF.run();
System.out.println("\n\nEnter 1 To Rerun
PreemptiveSJF\tEnter 2 To Main Menu\tPress Any Other Key To Exit");
choice = checkValidInputAndGetValue(sc);
if (choice == 1) {
preemptiveSJF.run();
} else if (choice == 2) {
break;
} else {
stop = true;
}
break;
}
case 4: {
Priority priority = new Priority("Priority");
priority.run();
System.out.println("\n\nEnter 1 To Rerun Priority\tEnter 2
To Main Menu\tPress Any Other Key To Exit");
choice = checkValidInputAndGetValue(sc);
if (choice == 1) {
priority.run();
} else if (choice == 2) {
break;
} else {
stop = true;
}
break;
}
case 5: {
RoundRobin roundRobin = new RoundRobin("RoundRobin");
roundRobin.run();
System.out.println("\n\nEnter 1 To Rerun RoundRobin\tEnter
2 To Main Menu\tPress Any Other Key To Exit");
choice = checkValidInputAndGetValue(sc);
if (choice == 1) {
roundRobin.run();
} else if (choice == 2) {
break;
} else {
stop = true;
}
break;
}
default: {
break;
}
}
}
13
P a g e | 14
1. FCFS
14
P a g e | 15
2. SJF
15
P a g e | 16
3. Preemptive SJF
16
P a g e | 17
4. Priority
5. Round-Robin
17
P a g e | 18
Conclusions
References
18
P a g e | 19
Contents
Introduction/Purpose.....................................................................................................20
Methods/Procedure........................................................................................................21
Output.............................................................................................................................25
Conclusion……………………………………………………………………………................27
References........................................................................................................................27
19
P a g e | 20
Introduction
Networking is a major branch of programming that is vital to connecting users through
devices. As such many programming languages have multiple ways to form connections users
and servers or between peers. For starting out programming, Java is one of the first languages
many programmers learn, and one of the interesting ways java can handle network
connections is through the use of Java Sockets.
We have prepared this tutorial to instruct how to use sockets in java by developing a chat
server between one server and many users.
This documentation is divided between client side and server side development.
➢ Java JDK
➢ packages
20
P a g e | 21
Methods/Procedure
We use the following steps to make multithreading chat room on client and Server side.
// The set of all the print writers for all the clients, used for
broadcast.
private static Set<PrintWriter> writers = new HashSet<>();
/**
21
P a g e | 22
/**
* Services this thread's client by repeatedly requesting a screen name
until a
* unique one has been submitted
*/
public void run() {
try {
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream(), true);
writers.remove(out);
}
if (name != null) {
System.out.println(name + " is leaving");
names.remove(name);
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + name + " has left");
}
}
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}
String serverAddress;
Scanner in;
PrintWriter out;
JFrame frame = new JFrame("Chat Room");
JTextField textField = new JTextField(50);
JTextArea messageArea = new JTextArea(16, 50);
// we have used port number 8989
textField.setEditable(false);
messageArea.setEditable(false);
frame.getContentPane().add(textField, BorderLayout.SOUTH);
frame.getContentPane().add(new JScrollPane(messageArea),
BorderLayout.CENTER);
frame.pack();
textField.setText("");
}
});
}
while (in.hasNextLine()) {
var line = in.nextLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName());
} else if (line.startsWith("NAMEACCEPTED")) {
this.frame.setTitle("Chatter - " +
line.substring(13));
textField.setEditable(true);
} else if (line.startsWith("MESSAGE")) {
messageArea.append(line.substring(8) + "\n");
}
}
}catch (Exception e) {
System.out.println("There is no Server running!");
}
finally {
frame.setVisible(false);
frame.dispose();
}
}
24
P a g e | 25
25
P a g e | 26
User 1 and user 2 left the chat the other will be notified
Conclusion
26
P a g e | 27
From this java project assignment, we have seen how to implement multithreading client sever
application in java programming on chat between process server and client. Using of threads
for having more than one clients served by one server.
3) Threads are independent, so it doesn't affect other threads if an exception occurs in a single
thread.
References
➢ Lecture notes , Henock Mulugeta (PhD)
➢ Google
➢ Tutorial point (https://www.tutorialspoint.com)
27
P a g e | 28
Contents
Introduction/Purpose.....................................................................................................29
Problem …………………………………………………..…………………………………….29
Solution.........................................................................................................................29
Implementation .............................................................................................................30
Resolving deadlock.........................................................................................................33
References......................................................................................................................35
6. 1. Introduction
The Dining Philosophers problem is one of the classic problems used to describe
synchronization issues in a multi-threaded environment and illustrate techniques for solving
them. Dijkstra first formulated this problem and presented it regarding computers accessing
tape drive peripherals.
28
P a g e | 29
The present formulation was given by Tony Hoare, who is also known for inventing the
quicksort sorting algorithm. In this article, we analyze this well-known problem and code a
popular solution.
7. 2. The Problem
The diagram above represents the problem. There are five silent philosophers (P1 – P5) sitting
around a circular table, spending their lives eating and thinking.
There are five forks for them to share (1 – 5) and to be able to eat, a philosopher needs to have
forks in both his hands. After eating, he puts both of them down and then they can be picked
by another philosopher who repeats the same cycle.
The goal is to come up with a scheme/protocol that helps the philosophers achieve their goal
8. 3. A Solution
An initial solution would be to make each of the philosophers follow the following protocol:
29
P a g e | 30
As the above pseudo code describes, each philosopher is initially thinking. After a certain
amount of time, the philosopher gets hungry and wishes to eat.
At this point, he reaches for the forks on his either side and once he's got both of them,
proceeds to eat. Once the eating is done, the philosopher then puts the forks down, so that
they're available for his neighbor.
9. 4. Implementation
We model each of our philosophers as classes that implement the Runnable interface so that we
can run them as separate threads. Each Philosopher has access to two forks on his left and right
sides:
We also have a method that instructs a Philosopher to perform an action – eat, think, or acquire
forks in preparation for eating:
30
P a g e | 31
As shown in the code above, each action is simulated by suspending the invoking thread for a
random amount of time, so that the execution order isn't enforced by time alone.
Now, let's implement the core logic of a Philosopher.
To simulate acquiring a fork, we need to lock it so that no two Philosopher threads acquire it at
the same time.
To achieve this, we use the synchronized keyword to acquire the internal monitor of the fork
object and prevent other threads from doing the same. We proceed with implementing
the run() method in the Philosopher class now:
31
P a g e | 32
This scheme exactly implements the one described earlier: a Philosopher thinks for a while and
then decides to eat.
After this, he acquires the forks to his left and right and starts eating. When done, he places the
forks down. We also add timestamps to each action, which would help us understand the
order in which events occur.
To kick start the whole process, we write a client that creates 5 Philosophers as threads and
starts all of them:
We model each of the forks as generic Java objects and make as many of them as there are
philosophers. We pass each Philosopher his left and right forks that he attempts to lock using
the synchronized keyword.
Running this code results in an output similar to the following. Your output will most likely
differ from the one given below, mostly because the sleep() method is invoked for a different
interval:
32
P a g e | 33
All the Philosophers initially start off thinking, and we see that Philosopher 1 proceeds to pick up
the left and right fork, then eats and proceeds to place both of them down, after which
`Philosopher 5` picks it up.
A deadlock is a situation where the progress of a system is halted as each process is waiting to
In this situation, each of the Philosophers has acquired his left fork, but can't acquire his right
fork, because his neighbor has already acquired it. This situation is commonly known as
the circular wait and is one of the conditions that results in a deadlock and prevents the
progress of the system.
deadlock situation we need to make sure that the circular wait condition is broken. There are
several ways to achieve this, the simplest one being the follows:
All Philosophers reach for their left fork first, except one who first reaches for his right fork.
We implement this in our existing code by making a relatively minor change in code:
The change comes in lines 17-19 of the above code, where we introduce the condition that
makes the last philosopher reach for his right fork first, instead of the left. This breaks the
circular wait condition and we can avert the deadlock.
Following output shows one of the cases where all the Philosophers get their chance to think
and eat, without causing a deadlock:
34
P a g e | 35
It can be verified by running the code several times that the system is free from the deadlock
situation that occurred before.
References
➢ Lecture notes , Henock Mulugeta (PhD)
➢ Google
➢ Tutorial point (https://www.tutorialspoint.com)
35