Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

given code: server.h #ifndef SERVER_H #define SERVER_H #include <iostream> #incl

ID: 3746418 • Letter: G

Question

given code:

server.h

#ifndef SERVER_H
#define SERVER_H

#include <iostream>
#include <vector>
#include <fstream>
#include <mutex>

using namespace std;

class Server
{
public:
Server();
Server(string, int);
~Server();
string getPiece(int);
private:
string *ascii;
mutex access;
};

#endif

server.cpp

#include "Server.h"
#include <unistd.h>
#include <time.h>

Server::Server(){}

Server::Server(string filename, int threads)
{
vector<string> loaded;
ascii = new string[threads];
ifstream in;
string line;
in.open(filename);
if (!in.is_open())
{
cout << "Could not open file " << filename << endl;
exit(1);
}
while(!in.eof())
{
getline(in, line);
loaded.push_back(line);
}
in.close();

int step = loaded.size()/threads;
string piece = "";

for (int i = 0; i < threads; ++i)
{
for (int j = step*i; j < ((step*i) + step); ++j)
{
if (j + 1 < loaded.size())
piece += loaded.at(j) + " ";
else
piece += loaded.at(j);
}
ascii[i] = piece;
piece = "";
}
}

Server::~Server()
{
delete []ascii;
}

string Server::getPiece(int piece)
{
srand(time(NULL));
if (rand()/static_cast<float>(RAND_MAX) > 0.80)
throw "500 Internal Server Error";
cout << "Getting piece number " << piece << endl;
string toReturn = ascii[piece];
return toReturn;
}

/file to implement

deadlock.cpp

#include <iostream>
#include <unistd.h>
#include "Server.h"

using namespace std;

Server *server;

void printToScreen(string toPrint)
{
/* Implement this function so that printing from each thread to stdout (i.e. using cout) doesn't clash with each other. */
}

void print(string out)
{
/* Output to file called deadlock.txt */
}

void lock(int choice)
{
/* Based on the choice, lock either the server or printer */
}

void unlock(int choice)
{
/* Based on the choice, unlock either the server or printer */
}

void spin(int index)
{
/* Wait until it is "index's" turn to write to the file. */
}

void evenThread(int index)
{
try
{
spin(index);

lock(0); // server
printToScreen("Thread " + to_string(index) + ": Lock acquired for Server ");
string piece = server->getPiece(index);

print(piece);

unlock(0);
printToScreen("Thread " + to_string(index) + ": Lock released for Server ");

unlock(1); // printer
printToScreen("Thread " + to_string(index) + ": Lock released for Printer ");
}
catch (const char *msg)
{
cerr << msg << endl;
}
}

void oddThread(int index)
{
try
{
lock(0); // server
printToScreen("Thread " + to_string(index) + ": Lock acquired for Server ");
string piece = server->getPiece(index);

spin(index);
print(piece);

unlock(0);
printToScreen("Thread " + to_string(index) + ": Lock released for Server ");

unlock(1); // printer
printToScreen("Thread " + to_string(index) + ": Lock released for Printer ");
}
catch (const char *msg)
{
cout << msg << endl;
}
}

int main(int argc, char const *argv[])
{
if (/*filename argument*/ != "" && /*thread count argument*/ != 0)
{
server = new Server(/*filename argument*/, /*thread count argument*/);

/* Fill in the main function code here */

delete server;
}
else
{
cout << "Please enter a file name and the number of threads to use!" << endl;
}

return 0;
}

Task 1 - Deadlock [9 Marks] a- te a mak . In this task you are required to im!plement a number of functions in the file deadlock.cpp. Thi AtiaR2^ T'he implementation of these functions shonld provide yon with two deadlock sita tions. You will need to use threads when implementing these functions. You may use lgli level C++ lineals OR pthreads lor llis purpose. You will also need lo use sollie locking mechanism to achieve mutual exclusion between threads. The methods you need to implement are as follows: 1. printToScreen(string toScreen) - Implement this function to deal with the racc condition on stdout (i.c. printing to the scrccn). If multiple thrcads try and output to the screen concurrently, much of the text being output wi collide with each other and create a line, or multiple lines, of difficlt to interpret text. This is what is meant by the race condition on stdout .oulpul(string toPri) Ths function writes the tring toPrin o a file called "deadlock.txt". Before opening the file you will need to output, to the screen, the string "Opening..." and before writing to the file output, to the screen, the string Writing.."

Explanation / Answer

PROGRAM:

#ifndef SERVER_H
#define SERVER_H

#include <iostream>
#include <iostream>
#include <thread>
#include <mutex>
#include <unistd.h>

using namespace std;

class Server
{
public:
Server();
Server(string, int);
~Server();
string getPiece(int);
private:
string *ascii;
mutex access;
};

//server.ccp

#include "Server.h"
#include
#include

Server::Server(){}

Server::Server(string filename, int threads)
{
vector loaded;
ascii = new string[threads];
ifstream in;
string line;
in.open(filename);
if (!in.is_open())
{
cout << "Could not open file " << filename << endl;
exit(1);
}
while(!in.eof())
{
getline(in, line);
loaded.push_back(line);
}
in.close();

int step = loaded.size()/threads;
string piece = "";

for (int i = 0; i < threads; ++i)
{
for (int j = step*i; j < ((step*i) + step); ++j)
{
if (j + 1 < loaded.size())
piece += loaded.at(j) + " ";
else
piece += loaded.at(j);
}
ascii[i] = piece;
piece = "";
}
}

Server::~Server()
{
delete []ascii;
}

string Server::getPiece(int piece)
{
srand(time(NULL));
if (rand()/static_cast(RAND_MAX) > 0.6)
throw "500 Internal Server Error";
cout << "Getting piece number " << piece << endl;
string toReturn = ascii[piece];
return toReturn;
}

// mutex.cpp

#include <iostream>

#include <unistd.h>

#include "Server.h"

#include <iostream>

#

include <fstream>

#include <string>

#include <cstdlib> // system()

#include <conio.h>

using namespace std;

Server *server;

void printToScreen(string toPrint)

{

/* Implement this function so that printing from each thread to stdout (i.e. using cout) doesn't clash with each other. */

}

void print(string out)

{

/* Output to file called deadlock.txt */

ofstream printer ("LPT1");

if(!printer)

{ return 1;

}

printer.puts(out);

printer.putc(' ');

printer.close();

}

void lock(int choice)

{

}

void unlock(int choice)

{

/* Based on the choice, unlock either the server or printer */

  

}

void spin(int index)

{

/* Wait until it is "index's" turn to write to the file. */

}

void evenThread(int index)

{

try

{

spin(index);

lock(0); // server

printToScreen("Thread " + to_string(index) + ": Lock acquired for Server ");

string piece = server->getPiece(index);

print(piece);

  

unlock(0);

printToScreen("Thread " + to_string(index) + ": Lock released for Server ");

  

unlock(1); // printer

printToScreen("Thread " + to_string(index) + ": Lock released for Printer ");

}

catch (const char *msg)

{

cerr << msg << endl;

}

}

void oddThread(int index)

{

try

{

lock(0); // server

printToScreen("Thread " + to_string(index) + ": Lock acquired for Server ");

string piece = server->getPiece(index);

spin(index);

print(piece);

  

unlock(0);

printToScreen("Thread " + to_string(index) + ": Lock released for Server ");

  

unlock(1); // printer

printToScreen("Thread " + to_string(index) + ": Lock released for Printer ");

}

catch (const char *msg)

{

cout << msg << endl;

}

}

int main(int argc, char const *argv[])

{

string fileString;

ifstream myfile ("mutex.txt");

if (myfile.is_open())

{

while ( getline (myfile,fileString) )

{

if (fileString != "" && argc!= 0)

{

server = new Server(fileString, argc);

  

/* Fill in the main function code here */

  

delete server;

}

else

{

cout << "Please enter a file name and the number of threads to use!" << endl;

}

}

myfile.close();

}

return 0;

}