Having problems with executing jobs using fork. The code is supposed to create one job and execute one job and repeat this multiple times. We are only supposed to use usleep in the jobgeneration() function.
We are having trouble sleeping and executing ctrl-c in the execute job function.
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iterator>
#include <vector>
#include <map>
#include <signal.h>
#include <unistd.h>
using namespace std;
void jobScheduler();
void setJobQueues();
void jobGenerator(int maximumQueueSize);
int createRandomJob();
int createRandomQuatnumInteger();
int selectJob();
void executeJob(int jobnumber);
string convertInt(int number);
int main() {
int pid;
int MAX_JOB_QUEUE_SIZE = 10;
srand(time(0));
// DONT UNCOMMENT SETJOBQUEUES!
//setJobQueues(); //Set up the priority job queues with chosen file and data structure
////////////////////////////////
//jobGenerator(10);
//selectJob();
//jobScheduler();
if(pid = fork() != 0){ //Parent, jobGenerator process
cout<<":pid from if "<<pid<<endl;
jobGenerator(MAX_JOB_QUEUE_SIZE); //generate random jobs and put them into priority queues. The priority queues must be protected in a critical region.
//exit(0);
}
else{ //Child, job scheduler process
cout<<":pid from else"<<pid<<endl;
jobScheduler(); //schedule and execute the jobs
exit(0);
}
//jobScheduler();
return 1;
}
void setJobQueues(){
ofstream file("queues.txt");
file<<endl<<endl<<endl;
file.close();
}
void jobGenerator(int maximumQueueSize){
int number = 0;
for(int i = 0; i<10; i++)
{
number = createRandomJob();
string numberString = convertInt(number);
cout<<"the number generated is "<<number<<endl;
//cout<<"numberString="<<numberString<<endl;
ifstream input;
input.open("queues.txt", ifstream::in);
string lineTask = "";
string lineServer = "";
string linePowerUser = "";
string lineUser = "";
int lineNumber = 0;
getline(input, lineTask);
getline(input, lineServer);
getline(input, linePowerUser);
getline(input, lineUser);
/*cout<<"before\n";
cout<<"line 1"<<lineTask<<endl;
cout<<"line 2"<<lineServer<<endl;
cout<<"line 3"<<linePowerUser<<endl;
cout<<"line 4"<<lineUser<<endl;*/
if(lineTask.length() == (maximumQueueSize*2)){
//cout<<"line is equal to max\n";
}
else if(lineTask.length() < (maximumQueueSize*2)){
if(number>=1 && number <=10){ //add to task queue
//cout<<"enter1\n";
lineTask.append(numberString+"|");
}
}
if(lineServer.length() == (maximumQueueSize*2)){
//cout<<"line is equal to max\n";
}
else if(lineServer.length() < (maximumQueueSize*2)){
if(number>=11 && number <=30){ //add to server queue
//cout<<"enter2\n";
int quant = createRandomQuatnumInteger();
string quantum = convertInt(quant);
lineServer.append(numberString+":"+quantum+"|");
}
}
if(linePowerUser.length() == (maximumQueueSize*2)){
//cout<<"line is equal to max\n";
}
else if(linePowerUser.length() < (maximumQueueSize*2)){
if(number>=31 && number <=50){ //add to power user queue
//cout<<"enter3\n";
linePowerUser.append(numberString+"|");
}
}
if(lineUser.length() == (maximumQueueSize*2)){
//cout<<"line is equal to max\n";
}
else if(lineUser.length() < (maximumQueueSize*2)){
if(number>=51 && number <=100){ //add to user queue
//cout<<"enter4\n";
lineUser.append(numberString+"|");
}
}
input.close();
ofstream output;
output.open("queues.txt", ofstream::out);
/*cout<<"after\n";
cout<<"line 1"<<lineTask<<endl;
cout<<"line 2"<<lineServer<<endl;
cout<<"line 3"<<linePowerUser<<endl;
cout<<"line 4"<<lineUser<<endl;*/
output<<lineTask<<endl;
output<<lineServer<<endl;
output<<linePowerUser<<endl;
output<<lineUser;
output.close();
usleep(50);
}
}
void jobScheduler(){
int i = 0;
int n = 0;
int pid;
while(i<10){ //schedule and run maximum N jobs
n = selectJob(); //pick a job from the priority queues
cout<<"job is"<<n<<endl;
if(n > 0){ //valid job id
if(pid = fork() == 0){ //child worker process
executeJob(n); //execute job
exit(0);
}
else
{
cout<<"enter else\n";
}
}
i++;
}
}
int createRandomJob(){
int randomNumber = 0;
randomNumber = rand() % 100 + 1; //return number between range 1 to 100
return randomNumber;
}
int createRandomQuatnumInteger(){
int randomNumber;
//srand(time(NULL)); //initialize random seed
randomNumber = rand() % 3; //return number between range 1 to 100
return randomNumber;
}
string convertInt(int number){
stringstream ss; //create a stringstream
ss << number; //add number to the stream
return ss.str(); //return a string with the contents of the stream
}
void signalCall(int param) {
cout << endl << "Resuming Execution..." << endl;
sleep(1);
signal(SIGINT, SIG_DFL);
}
void executeJob(int jobNumber){
// If job ID is in task_queue just print the job id
if(jobNumber >=1 && jobNumber <=10){
cout << endl << "TASK_QUEUE - JOB ID: " << jobNumber << endl;
}
// If job ID is in server_queue have it run and print its number also say its round robin
if(jobNumber >=11 && jobNumber <=30){
cout << endl << "SERVER_QUEUE - JOB ID: " << jobNumber << endl;
}
// if job ID is in power_user queue block here for the CNTRL C user input
if(jobNumber >=31 && jobNumber <=50){
cout << endl << "POWER_USER_QUEUE - JOB ID: " << jobNumber << endl;
cout << "Hit CNTL C to continue" << endl;
signal(SIGINT,signalCall);
}
// if job ID is in user_queue run then sleep for 5 seconds
if(jobNumber>=51 && jobNumber <=100){
cout << endl << "USER_QUEUE - JOB ID: " << jobNumber << endl;
sleep(5);
}
}
// Splits the line in the file up so we can get at each job
// This is reused from the first project
inline vector<string> split(const string& s, const string& f) {
vector<string> temp;
if (f.empty()) {
temp.push_back(s);
return temp;
}
// Iterator to go throught the string
typedef string::const_iterator iter;
const iter::difference_type f_size(distance(f.begin(), f.end()));
iter i(s.begin());
for (iter pos; (pos = search(i, s.end(), f.begin(), f.end())) != s.end();) {
temp.push_back(string(i, pos));
advance(pos, f_size);
i = pos;
}
temp.push_back(string(i, s.end()));
return temp;
}
// This one checks that file for jobs. It should first look at the top line since that is highest priority. THen it will move on down.
// I know I made all my functions void, but you'll have to change return types to match things.
// Select job should return the job ID
int selectJob() {
int lineNumber = 0;
string line = "";
int jobID;
string IDs[4];
// Open the file so we can read from it
ifstream input ("queues.txt");
// Get 4 lines from the file and store each as an entry in the IDs array
for (int i = 0; i < 4; i++) {
getline(input, line);
IDs[lineNumber] = line;
lineNumber++;
}
input.close();
// Just for testing
/*cout << endl;
for (int i = 0; i < 4; i++) {
cout << "Line" << i+1 << ": "<< IDs[i] << endl;
}
cout << endl;*/
/////////////////////
// Line 1 TASK_QUEUE/
/////////////////////
if (IDs[0].length() > 1) {
//cout<<"TASK QUEUE\n";
// call the split function to make a vector of each process ID
const vector<string> jobs(split(IDs[0], "|"));
//cout<<"numbernumbernumber"<<jobs[0].c_str()<<endl;
jobID = atoi(jobs[0].c_str()); // Converts the string to an int
// Cut the job out of the file and assign the new job list in its place
string newString = IDs[0].substr(jobs[0].length() + 1, IDs[0].length());
//cout<<"the new string from 1 is"<<newString<<endl;
IDs[0] = newString;
// Open the file and clear it
// Then rewrite the updated information to it
ofstream output;
output.open("queues.txt", ofstream::out | ios::trunc);
for (int i = 0; i < 4; i++) {
output << IDs[i] << endl;
//cout<<"the data being written to the file from 1 is"<<IDs[i]<<endl;
}
output.close();
return jobID;
//exit(0);
}
// REMOVE JOB WHEN QUANT IS ZERO
///////////////////////
// Line 2 SERVER_QUEUE/
///////////////////////
if (IDs[1].length() > 1) {
// call the split function to make a vector of each process ID
const vector<string> jobs(split(IDs[1], "|"));
// Split it again but with the : for the quantum time
const vector<string> quantum(split(jobs[0], ":"));
//cout<<"numbernumbernumber"<<jobs[1].c_str()<<endl;
int quant = atoi(quantum[1].c_str()); // Converts the string to an int
quant--; // Decrease the quantum time by 1
jobID = atoi(jobs[0].c_str()); // Converts the string to an int
//cout << "JOBID: " << jobID << endl;
//cout << "quant: " << quant << endl;
// Cut the job out of the file and assign the new job list in its place
string newString = IDs[1].substr(jobs[0].length() + 1, IDs[1].length());
//cout<<"the new string is"<<newString<<endl;
// These two calls to stringstream as used to convert the integer
// values into strings that we can concatenate to put back into the file
string jobIDString;
stringstream out;
out << jobID;
jobIDString = out.str();
string quantString;
stringstream out2;
out2 << quant;
quantString = out2.str();
// Append the job and the decremented quantum time to the end
// of the queue
if(quant > 0) {
newString = newString + jobIDString + ":" + quantString + "|";
}
//cout << endl << endl << newString << endl;
IDs[1] = newString;
// Open the file and clear it
// Then rewrite the updated information to it
ofstream output;
output.open("queues.txt", ofstream::out | ios::trunc);
for (int i = 0; i < 4; i++) {
output << IDs[i] << endl;
//cout<<"the data being written to the file from 2 is"<<IDs[i]<<endl;
}
output.close();
return jobID;
//exit(0);
}
///////////////////////////
// Line 3 POWER_USER_QUEUE/
///////////////////////////
if (IDs[2].length() > 1) {
// call the split function to make a vector of each process ID
const vector<string> jobs(split(IDs[2], "|"));
//cout<<"numbernumbernumber"<<jobs[2].c_str()<<endl;
jobID = atoi(jobs[0].c_str()); // Converts the string to an int
// Cut the job out of the file and assign the new job list in its place
string newString = IDs[2].substr(jobs[0].length() + 1, IDs[2].length());
//cout<<"the new string from 3 is"<<newString<<endl;
IDs[2] = newString;
// Open the file and clear it
// Then rewrite the updated information to it
ofstream output;
output.open("queues.txt", ofstream::out | ios::trunc);
for (int i = 0; i < 4; i++) {
output << IDs[i] << endl;
//cout<<"the data being written to the file from 3 is"<<IDs[i]<<endl;
}
output.close();
return jobID;
//exit(0);
}
/////////////////////
// Line 4 USER_QUEUE/
/////////////////////
if (IDs[3].length() > 1) {
// call the split function to make a vector of each process ID
const vector<string> jobs(split(IDs[3], "|"));
jobID = atoi(jobs[0].c_str()); // Converts the string to an int
//cout<<"numbernumbernumber"<<jobs[3].c_str()<<endl;
// Cut the job out of the file and assign the new job list in its place
string newString = IDs[3].substr(jobs[0].length() + 1, IDs[3].length());
//cout<<"the new string from 4 is"<<newString<<endl;
IDs[3] = newString;
// Open the file and clear it
// Then rewrite the updated information to it
ofstream output;
output.open("queues.txt", ofstream::out | ios::trunc);
for (int i = 0; i < 4; i++) {
output << IDs[i] << endl;
//cout<<"the data being written to the file from 4 is"<<IDs[i]<<endl;
}
output.close();
return jobID;
//exit(0);
}
else {
return -1;
}
}