patterncppModerate
First-come first-serve job scheduling algorithm
Viewed 0 times
comeschedulingalgorithmfirstservejob
Problem
I tried to make the code for implementation of first-come first-serve job scheduling algorithm as used by operating systems.
How can I make it better?
I am using turbo C++ compiler
How can I make it better?
I am using turbo C++ compiler
#include
#include
#include
struct process//contains information about processes in waiting queue
{
int waitt;
int etime;
char name[32];
struct process * next;
};
void inc( struct process * q)//increases wait time of all processes in wait queue
{
while(q!=0)
{
q->waitt++;
q=q->next;
}
}
int pop(struct process** q)//remove process from wait queue to run state returns wait time of process
{
int wait=(*q)->waitt;
struct process* t=*q;
*q=(*q)->next;
delete t;
return wait;
}
void addnode(struct process** q)//add new process to wait queue
{
struct process *temp=new (struct process);
cout>temp->name;
do
{
cout>temp->etime;
}while(temp->etimenext=0;
temp->waitt=0;
if(*q==0)
*q=temp;
else
{
struct process* t=*q;
while(t->next!=0)
t=t->next;
t->next=temp;
}
}
int main(void)
{
clrscr();
int e=1,wait=0,p=0,tt=1;
struct process* q=0,*t;
//add first process
addnode(&q);
e=q->etime;//Burst time of runing process
coutnamewaitt;
coutetime;
coutnamewaitt<<"time units\n";
p++;
wait+=pop(&q);
}
}
delay(100);
cout<<tt++<<" ";//to show total time units since start of first process
}while(q!=0||e!=0);//if process ended also no process in wait queue end loop
cout<<"\n\nTotal no. of prcesses executed ="<<p;
cout<<"\nTotal wait time for all prcesses executed ="<<wait;
cout<<"\nAverage wait time for prcesses executed ="<<wait/(float)p;
getch();
return 0;
}Solution
I think this question would actually benefit from both a C review (just change the
This post will be a C++ review.
Please note that the Turbo C++ compiler is not available to me, so my suggestions will revolve around the C++98/03 standard.
My first bit of advice would be to switch to an object-oriented approach.
Turn
In
Refactor
Make
Rename
Take out the user-input logic from
This will improve their flexibility.
A function should only do one thing, and do it well.
For function parameters, prefer the use of references over the use of pointers.
This will save you from having to check for
Here is an idea of what a
This would encapsulate your variables and (for the most part) make them read-only.
Because the
Here is an idea of what a
This, once again, encapsulates your variables while still providing useful functionality.
Here's what a constructor implementation might look like:
What you see here is a constructor initialization list. It is important to initialize your variables or else you may suffer from subtle bugs.
Here is a destructor for the
This makes sure all of our resources (memory in this case) are cleaned up when an instance of this class goes out of scope. This strategy is called RAII. RAII is important for writing exception-safe code.
Here is an example implementation of all of the above combined (somewhat sloppily):
```
#include
#include
#include
class process_queue ;
class process
{
public:
process (const std::string &name, const int burst_time = 0, const int wait_time = 0) ;
std::string name () const ;
int burst_time () const ;
int wait_time () const ;
const process* next () const ;
process* next () ;
void decrement_burst_time (const int time) ;
private:
int burst_time_;
int wait_time_;
std::string name_;
process *next_;
friend std::ostream& operatorname () ;
}
else {
os next_ = temp ;
if (head_ == tail_) {
head_->next_ = temp ;
}
tail_ = tail_->next_ ;
}
else {
tail_ = temp ;
head_ = tail_ ;
}
++size_ ;
}
void process_queue::increment_all_wait_times (const int wait)
{
process *temp = head_ ;
while (temp != NULL) {
temp->wait_time_ += wait ;
temp = temp->next_ ;
}
}
// Pops the head off.
process process_queue::pop ()
{
if (head_ == NULL) {
throw std::range_error ("process_queue::pop() called while the process_queue was empty.") ;
}
process ret = *head_ ;
process *temp = head_ ;
head_ = head_->next_ ;
delete temp ;
--size_ ;
return ret ;
}
bool process_queue::empty () const
{
return (size_ == 0) ;
}
size_t process_queue::size () const
{
return size_ ;
}
std::o
cout's to printf, etc) and a C++ review since you seem to be using a very C-orientated programming style. This post will be a C++ review.
Please note that the Turbo C++ compiler is not available to me, so my suggestions will revolve around the C++98/03 standard.
My first bit of advice would be to switch to an object-oriented approach.
Turn
process into a class and create a second class, process_queue. In
process, replace char name [32] with std::string name. This way, you don't have to worry about buffer overflows. Refactor
inc(), pop(), and addnode() into member functions for the new class process_queue.Make
pop() return a process instead of an int. This is because you have a queue of processs, not a queue of ints.Rename
inc() to something more readable like increment_all_wait_times(). That's a long name, but your code will be self-documenting. Take out the user-input logic from
inc(), pop(), and addnode().This will improve their flexibility.
A function should only do one thing, and do it well.
For function parameters, prefer the use of references over the use of pointers.
This will save you from having to check for
NULL.Here is an idea of what a
process class might look like: class process
{
public:
process (const std::string &name, const int burst_time = 0, const int wait_time = 0) ;
// getters
std::string name () const ;
int burst_time () const ;
int wait_time () const ;
const process* next () const ;
process* next () ;
void decrement_burst_time (const int time) ;
private:
int burst_time_;
int wait_time_;
std::string name_;
process *next_;
friend std::ostream& operator<< (std::ostream &os, const process &proc) ;
friend class process_queue ;
};This would encapsulate your variables and (for the most part) make them read-only.
Because the
process_queue class is tightly coupled with this class, I would make it a friend class. There are two versions of the next() method for the sake of const-correctness. Here is an idea of what a
process_queue class might look like: class process_queue
{
public:
process_queue () ;
~process_queue () ;
bool empty () const ;
void add_node (const process &proc) ;
void increment_all_wait_times (const int wait) ;
process pop () ;
size_t size () const ;
friend std::ostream & operator<< (std::ostream &os, const process_queue &pq) ;
private:
size_t size_ ;
process *head_;
process *tail_; // for O(1) insertions
};This, once again, encapsulates your variables while still providing useful functionality.
Here's what a constructor implementation might look like:
process::process (const std::string &name, const int burst_time, const int wait_time)
: name_ (name), burst_time_ (burst_time), wait_time_ (wait_time), next_ (NULL)
{
}What you see here is a constructor initialization list. It is important to initialize your variables or else you may suffer from subtle bugs.
Here is a destructor for the
process_queue class:process_queue::~process_queue ()
{
while (size_ > 0) {
this->pop () ;
}
}This makes sure all of our resources (memory in this case) are cleaned up when an instance of this class goes out of scope. This strategy is called RAII. RAII is important for writing exception-safe code.
Here is an example implementation of all of the above combined (somewhat sloppily):
```
#include
#include
#include
class process_queue ;
class process
{
public:
process (const std::string &name, const int burst_time = 0, const int wait_time = 0) ;
std::string name () const ;
int burst_time () const ;
int wait_time () const ;
const process* next () const ;
process* next () ;
void decrement_burst_time (const int time) ;
private:
int burst_time_;
int wait_time_;
std::string name_;
process *next_;
friend std::ostream& operatorname () ;
}
else {
os next_ = temp ;
if (head_ == tail_) {
head_->next_ = temp ;
}
tail_ = tail_->next_ ;
}
else {
tail_ = temp ;
head_ = tail_ ;
}
++size_ ;
}
void process_queue::increment_all_wait_times (const int wait)
{
process *temp = head_ ;
while (temp != NULL) {
temp->wait_time_ += wait ;
temp = temp->next_ ;
}
}
// Pops the head off.
process process_queue::pop ()
{
if (head_ == NULL) {
throw std::range_error ("process_queue::pop() called while the process_queue was empty.") ;
}
process ret = *head_ ;
process *temp = head_ ;
head_ = head_->next_ ;
delete temp ;
--size_ ;
return ret ;
}
bool process_queue::empty () const
{
return (size_ == 0) ;
}
size_t process_queue::size () const
{
return size_ ;
}
std::o
Code Snippets
class process
{
public:
process (const std::string &name, const int burst_time = 0, const int wait_time = 0) ;
// getters
std::string name () const ;
int burst_time () const ;
int wait_time () const ;
const process* next () const ;
process* next () ;
void decrement_burst_time (const int time) ;
private:
int burst_time_;
int wait_time_;
std::string name_;
process *next_;
friend std::ostream& operator<< (std::ostream &os, const process &proc) ;
friend class process_queue ;
};class process_queue
{
public:
process_queue () ;
~process_queue () ;
bool empty () const ;
void add_node (const process &proc) ;
void increment_all_wait_times (const int wait) ;
process pop () ;
size_t size () const ;
friend std::ostream & operator<< (std::ostream &os, const process_queue &pq) ;
private:
size_t size_ ;
process *head_;
process *tail_; // for O(1) insertions
};process::process (const std::string &name, const int burst_time, const int wait_time)
: name_ (name), burst_time_ (burst_time), wait_time_ (wait_time), next_ (NULL)
{
}process_queue::~process_queue ()
{
while (size_ > 0) {
this->pop () ;
}
}#include <iostream>
#include <string>
#include <stdexcept>
class process_queue ;
class process
{
public:
process (const std::string &name, const int burst_time = 0, const int wait_time = 0) ;
std::string name () const ;
int burst_time () const ;
int wait_time () const ;
const process* next () const ;
process* next () ;
void decrement_burst_time (const int time) ;
private:
int burst_time_;
int wait_time_;
std::string name_;
process *next_;
friend std::ostream& operator<< (std::ostream &os, const process &proc) ;
friend class process_queue ;
};
process::process (const std::string &name, const int burst_time, const int wait_time)
: name_ (name), burst_time_ (burst_time), wait_time_ (wait_time), next_ (NULL)
{
}
std::string process::name () const
{
return name_ ;
}
int process::burst_time () const
{
return burst_time_ ;
}
int process::wait_time () const
{
return wait_time_ ;
}
const process* process::next () const
{
return next_ ;
}
process* process::next ()
{
return next_ ;
}
void process::decrement_burst_time (const int time)
{
burst_time_ -= time ;
}
std::ostream & operator<< (std::ostream &os, const process &proc)
{
os << "{Name = " << proc.name ()
<< ", Wait time = " << proc.wait_time ()
<< ", Burst time = " << proc.burst_time ()
<< ", Next = " ;
if (proc.next () != NULL) {
os << proc.next ()->name () ;
}
else {
os << "None" ;
}
os << "}" ;
return os ;
}
class process_queue
{
public:
process_queue () ;
~process_queue () ;
bool empty () const ;
void add_node (const process &proc) ;
void increment_all_wait_times (const int wait) ;
process pop () ;
size_t size () const ;
friend std::ostream & operator<< (std::ostream &os, const process_queue &pq) ;
private:
size_t size_ ;
process *head_;
process *tail_; // for O(1) insertions
};
process_queue::process_queue () : head_ (NULL), tail_ (NULL), size_ (0)
{
}
void process_queue::add_node (const process &proc)
{
process *temp = new process (proc) ;
if (tail_ != NULL) {
tail_->next_ = temp ;
if (head_ == tail_) {
head_->next_ = temp ;
}
tail_ = tail_->next_ ;
}
else {
tail_ = temp ;
head_ = tail_ ;
}
++size_ ;
}
void process_queue::increment_all_wait_times (const int wait)
{
process *temp = head_ ;
while (temp != NULL) {
temp->wait_time_ += wait ;
temp = temp->next_ ;
}
}
// Pops the head off.
process process_queue::pop ()
{
if (head_ == NULL) {
throw std::range_error ("process_queue::pop() called while the process_queue was empty.") ;
}
process ret = *head_ ;
process *temp = head_ ;
head_ = head_->next_ ;
delete temp ;
--size_ ;
return ret ;
}
bool process_queue::empty () const
{
return (size_ == 0) ;
}
size_t process_queuContext
StackExchange Code Review Q#41101, answer score: 11
Revisions (0)
No revisions yet.