Question: Thread programming a. Please cut, paste and finish the following program composed of 4 separate files below. b. main() should: Create 2 child threads, both

Thread programming

a. Please cut, paste and finish the following program composed of 4 separate files below.

b. main() should:

Create 2 child threads, both that run evaluate(). The evaluate() function should be passed the address of nodeBuffer.

Run makeNode() NUM_PROBLEMS times, and put the returned node address in nodeBuffer.

Wait for both child threads to finish

c. evaluate() should NUM_PROBLEM/2 times do:

Save the value returned by the pullOut() method into a Node* variable.

Print the iteration number, the node expression (obtainable as a C-string with the expression: nodePtr->toString().c_str()) and the value the node evaluates to (nodePtr->eval()).

delete the node pointer variable

After the loop, the function should just return(NULL).

Stop and try your program now. It is multi-threaded, but not thread-safe. It should not work properly.

d. Make NodeBuffer thread safe by giving it the necessary mutex(es) and condition(s). Where is/are the critical sections? Be sure to destroy your variables in ~NodeBuffer()!

/*-------------------------------------------------------------------------* *--- ---* *--- mathSolverHeader.h ---* *--- ---* *--- This file defines constants and includes other files ---* *--- necessary for the math generator and solver program. ---* *--- ---* *--- ---- ---- ---- ---- ---- ---- ---- ---- ---* *--- ---* *--- ---* *-------------------------------------------------------------------------*/ 
#include #include #include #include #include #include #include 

#include

// PURPOSE: To tell the maximum value that a tree can have. const int MAX_VALUE = 64; // PURPOSE: To tell how many problems to do. const int NUM_PROBLEMS = 4096; #include "Node.h" #include "NodeBuffer.h" /*-------------------------------------------------------------------------* *--- ---* *--- Node.h ---* *--- ---* *--- This file defines classes for nodes used to represent math ---* *--- expressions. ---* *--- ---* *--- ---- ---- ---- ---- ---- ---- ---- ---- ---* *--- ---* *--- ---* *-------------------------------------------------------------------------*/ // PURPOSE: To distinguish among the mathematical operators. typedef enum { ADD_OP, SUBTRACT_OP, MULTIPLY_OP, DIVIDE_OP, NUM_OPS } operator_ty; // PURPOSE: To serve as the base class for the Node classes. class Node { public : Node () { } virtual ~Node () { } virtual double eval () const = 0; virtual std::string toString () const = 0; }; // PURPOSE: To represent a constant. class ConstNode : public Node { double constant_; public : ConstNode () : Node(), constant_((double)((rand() % MAX_VALUE) + 1) ) { } double eval () const { return(constant_); } std::string toString () const { std::ostringstream stream; stream << constant_; return(stream.str()); } }; // PURPOSE: To return a randomly generated Node. extern Node* makeNode (); // PURPOSE: To represent an operation. class OperatorNode : public Node { operator_ty operator_; Node* lhsPtr_; Node* rhsPtr_; public : OperatorNode () : Node(), operator_((operator_ty)(rand() % NUM_OPS)), lhsPtr_(makeNode()), rhsPtr_(makeNode()) { } ~OperatorNode () { delete(rhsPtr_); delete(lhsPtr_); } double eval () const { double lhs = lhsPtr_->eval(); double rhs = rhsPtr_->eval(); double result; switch (operator_) { case ADD_OP : result = lhs + rhs; break; case SUBTRACT_OP : result = lhs - rhs; break; case MULTIPLY_OP : result = lhs * rhs; break; case DIVIDE_OP : result = lhs / rhs; break; } return(result); } std::string toString () const { std::ostringstream stream; const char* operatorNameCPtr; switch (operator_) { case ADD_OP : operatorNameCPtr = " + "; break; case SUBTRACT_OP : operatorNameCPtr = " - "; break; case MULTIPLY_OP : operatorNameCPtr = " * "; break; case DIVIDE_OP : operatorNameCPtr = " / "; break; } stream << "(" << lhsPtr_->toString() << operatorNameCPtr << rhsPtr_->toString() << ")"; return(stream.str()); } }; /*-------------------------------------------------------------------------* *--- ---* *--- NodeBuffer.h ---* *--- ---* *--- This file defines a class that implements a thread-safe ---* *--- buffer of pointers to math expressions. ---* *--- ---* *--- ---- ---- ---- ---- ---- ---- ---- ---- ---* *--- ---* *--- Version 1a 2018 February 22 Joseph Phillips ---* *--- ---* *-------------------------------------------------------------------------*/ class NodeBuffer { enum { SIZE = 16 }; Node* array_[SIZE]; int inIndex_; int outIndex_; int numItems_; public : NodeBuffer () { for (int i = 0; i < SIZE; i++) { array_[i] = NULL; } inIndex_ = outIndex_ = numItems_ = 0; } ~NodeBuffer () { } int getNumItems () const { return(numItems_); } void putIn (Node* nodePtr) { while (getNumItems() >= SIZE) { } array_[inIndex_] = nodePtr; inIndex_++; numItems_++; if (inIndex_ >= SIZE) inIndex_ = 0; } Node* pullOut () { while (getNumItems() <= 0) { } Node* toReturn = array_[outIndex_]; array_[outIndex_] = NULL; outIndex_++; numItems_--; if (outIndex_ >= SIZE) outIndex_ = 0; return(toReturn); } }; /*-------------------------------------------------------------------------* *--- ---* *--- mathSolver.cpp ---* *--- ---* *--- This file defines the high-level functions of the math ---* *--- generator and solver program. ---* *--- ---* *--- ---- ---- ---- ---- ---- ---- ---- ---- ---* *--- ---* *--- ---* *-------------------------------------------------------------------------*/ // // Compile with: // $ g++ mathSolver.cpp -o mathSolver -lpthread -g // #include "mathSolverHeader.h" void* evaluate (void* vPtr ) { NodeBuffer* nodeBufferPtr = (NodeBuffer*)vPtr; // YOUR CODE HERE } // PURPOSE: To return a randomly generated Node. Node* makeNode () { return( (rand() % 3) ? (Node*)new ConstNode() : (Node*)new OperatorNode() ); } int main (int argc, char* argv[] ) { NodeBuffer nodeBuffer; pthread_t consumer0; pthread_t consumer1; int toReturn = EXIT_SUCCESS; srand( (argc < 2) ? getpid() : atoi(argv[1]) ); // YOUR CODE HERE return(toReturn); } 

Sample output:

$ ./mathSolver 10 Made 0 Made 1 Made 2 Made 3 Made 4 Made 5 Made 6 Made 7 Made 8 Made 9 Made 10 Made 11 Made 12 Made 13 Made 14 Made 15 Made 16 Made 17 0 25 = 25.000000 1 54 = 54.000000 Made 18 Made 19 2 (24 - 4) = 20.000000 Made 20 3 54 = 54.000000 Made 21 4 (14 - (61 * (22 + 13))) = -2121.000000 Made 22 5 60 = 60.000000 6 55 = 55.000000 Made 23 Made 24 7 ((18 + ((33 + 36) / (47 - (1 / 22)))) / 2) = 9.734753 8 (59 - 59) = 0.000000 Made 25 ... Made 4089 2025 4 = 4.000000 Made 4090 2026 30 = 30.000000 Made 4091 Made 4092 2027 9 = 9.000000 Made 4093 2028 ((56 * 31) - 16) = 1720.000000 Made 4094 2029 ((59 / 60) / ((44 / 60) - 61)) = -0.016316 Made 4095 2030 (2 / (23 - 14)) = 0.222222 2031 41 = 41.000000 2032 49 = 49.000000 2033 ((35 * (35 - 32)) + 63) = 168.000000 2034 62 = 62.000000 2035 ((((41 / 4) - 18) / 20) * (((6 / 43) + (63 / 35)) + 46)) = -18.576570 2036 37 = 37.000000 2037 ((2 - ((((47 * ((24 / 28) - 48)) + 7) + (3 / 55)) - 59)) - 48) = 2221.659740 2038 11 = 11.000000 2039 (25 - 31) = -6.000000 2040 ((((40 * (14 + 25)) / 46) * 7) - (20 * (15 * (50 + (22 / 63))))) = -14867.370600 2041 38 = 38.000000 2042 (20 - 46) = -26.000000 2043 (58 * ((16 * 27) * ((36 - 61) / 12))) = -52200.000000 2044 (33 / 11) = 3.000000 2045 48 = 48.000000 2046 31 = 31.000000 2047 19 = 19.000000 

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Databases Questions!