Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

***UTILIZING C++*** PLEASE SHOW OUTPUT OF WORKING PROGRAM! buyTheCandy.cpp Overview: A package of 4 candy candies cost 100 cents. (It can be 1 USD, 1

***UTILIZING C++***

PLEASE SHOW OUTPUT OF WORKING PROGRAM!

buyTheCandy.cpp

Overview:

A package of 4 candy candies cost 100 cents. (It can be 1 USD, 1 Euro, 1 whatever). Four siblings (brothers or sisters) want a candy, and each has some money. Unfortunately, probably none of the siblings has enough money to buy the candies by themself. So they will all pool their money and jointly buy the candy.

There are 3 classes:

Coin: Represents some money

Purse: Implements a container (a linked list) of Coin instances.

CommonPurse: a thread-safe version of Purse

Each sibling has their money in a Purse instance. Additionally, there is a CommonPurse called sharedPurse to which all siblings will add their money. Because each sibling is implemented with its own thread, the individual Purse instances do not need to be thread safe. However, sharedPurse needs to be made thread-safe because all four threads can access it.

Cut-and-paste the following:

/*-------------------------------------------------------------------------* *--- ---* *--- buyTheCandy.cpp ---* *--- ---* *--- This file defines a program that exercises linked list and ---* *--- threading skills by simulating 4 children pooling their money ---* *--- to buy a pack of candy. ---* *--- ---* *--- ---- ---- ---- ---- ---- ---- ---- ---- ---* *--- ---* *--- ---* *--- ---* *-------------------------------------------------------------------------*/ /* * $ g++ -lpthread -g buyTheCandy.cpp -o buyTheCandy */ //-- Standard inclusions: --// #include  #include  #include  #include  //-- Constants: --// // PURPOSE: To the names of the children const char* CHILD_NAME_ARRAY[] = {"Alice", "Bob", "Cathy", "David" }; // PURPOSE: To tell the number of children. const int NUM_CHILDREN = sizeof(CHILD_NAME_ARRAY)/sizeof(const char*); // PURPOSE: To tell the possible denominations of the Coin instances. const int COIN_DENOMINATION_ARRAY[] = {1,5,10,25}; // PURPOSE: To tell the number of coins in each new Purse. const int NUM_COINS_PER_NEW_PURSE = 4; // PURPOSE: To tell the number of denominations. const int NUM_DENOMINATIONS = sizeof(COIN_DENOMINATION_ARRAY)/sizeof(int); // PURPOSE: To tell how much money needs to be collected to buy the candy. const int CANDY_COST = 100; //-- Classes: --// // PURPOSE: To represent coins. class Coin { // I. Member vars: // PURPOSE: To tell the denomination of '*this' Coin instance. int denomination_; // PURPOSE: To hold the address of the next Coin after '*this' one, // or 'NULL' if there is no such Coin instance. Coin* nextPtr_; // II. Disallowed auto-generated methods: // No default constructor: Coin (); // No copy constructor: Coin (const Coin&); // No copy assignment op: Coin operator= (const Coin&); protected : // III. Protected methods: public : // IV. Constructor(s), assignment op(s), factory(s) and destructor: // PURPOSE: To make a coin of denomination 'newDom'. No return value. Coin (int newDom ) : denomination_(newDom), nextPtr_(NULL) { } // PURPOSE: To release the resources of '*this'. No parameters. // No return value. ~Coin () { } // V. Accessors: // PURPOSE: To return the denomination of '*this' Coin instance. // No parameters. int getDenomination () const { return(denomination_); } // PURPOSE: To return the address of the next Coin after '*this' one, // or 'NULL' if there is no such Coin instance. No parameters. Coin* getNextPtr () const { return(nextPtr_); } // VI. Mutators: // PURPOSE: To note that the Coin instance with address 'coinPtr' comes // after '*this' one. No return value. void setNextPtr (Coin* coinPtr ) { nextPtr_ = coinPtr; } // VII. Methods that do main and misc work of class: // PURPOSE: To create and return the address of a random coin. // No parameters. static Coin* makeRandom () { // I. Application validity check: // II. Create and return a coin: return(new Coin(COIN_DENOMINATION_ARRAY[rand() % NUM_DENOMINATIONS])); } }; // PURPOSE: To implement a list of Coin instances. class Purse { // 0. Constants: enum { NO_OWNER_INDEX = -1 }; // I. Member var: // PURPOSE: To hold the index of the name of the owner of '*this' Purse // instance, or 'NO_OWNER_INDEX' if '*this' has no owner. int index_; // ADD YOUR VARIABLES HERE // II. Disallowed auto-generated methods: // No copy constructor: Purse (const Purse&); // No copy-assignment op: Purse operator= (const Purse&); protected : // III. Protected methods: public : // IV. Constructor(s), assignment op(s), factory(s) and destructor: // PURPOSE: To initialize '*this' to an empty purse Purse () : index_(NO_OWNER_INDEX) { // INITIALIZE YOUR VARS HERE } // PURPOSE: To initialize '*this' Purse instance to have // NUM_COINS_PER_NEW_PURSE random Coin instances owned by the child with // index 'newIndex'. No return value. Purse (int newIndex ) : index_(newIndex) { // INITIALIZE YOUR VARS HERE for (int i = 0; i // GET RID OF YOUR VARS HERE } // V. Accessors: // PURPOSE: To return the index of the name of the owner of '*this' Purse // instance, or 'NO_OWNER_INDEX' if '*this' has no owner. int getIndex () const { return(index_); } // PURPOSE: To return the name of the owner of '*this' Purse instance. // No parameters. const char* getOwnerNameCPtr() const { return( (getIndex() == NO_OWNER_INDEX) ? "common" : CHILD_NAME_ARRAY[getIndex()] ); } // PURPOSE: To return the value of the money in '*this' wallet. // No parameters. int getValue () const { const Coin* run; int sum = 0; // YOUR CODE HERE return(sum); } // PURPOSE: To tell the number of Coin instances in '*this'. int getNumCoins () const { return(numCoins_); } // VI. Mutators: // PURPOSE: To add the Coin with address 'coinPtr' to '*this' Purse. // No return value. void addToBack (Coin* coinPtr ) { // YOUR CODE HERE } // PURPOSE: To remove the Coin at the beginning of '*this' and return // its address. No parameters. Coin* removeFromFront () { Coin* returnMe = NULL; // YOUR CODE HERE return(returnMe); } // VII. Methods that do main and misc. work of class: // PURPOSE: To print the status of '*this' Purse to 'stdout'. // No parameters. No return value. void print () const { printf ("%s has %d coins worth %d cents. ", getOwnerNameCPtr(),getNumCoins(),getValue() ); } }; // PURPOSE: To implement a thread-safe version of Purse. class CommonPurse : public Purse { // I. Member vars: // ADD YOUR VARIABLES HERE // PURPOSE: To tell the current turn. int turn_; // II. Disallowed auto-generated methods: // No copy constructor: CommonPurse (const CommonPurse&); // No copy assignment op: CommonPurse operator= (const CommonPurse&); protected : // III. Protected methods: public : // IV. Constructor(s), assignment op(s), factory(s) and destructor: // PURPOSE: To initialize '*this' to an empty shared Purse instance. CommonPurse () : turn_(NUM_CHILDREN-1) { // INITIALIZE YOUR VARS HERE } // PURPOSE: To release the resources of '*this'. No parameters. // No return value. ~CommonPurse () { // GET RID OF YOUR VARS HERE } // V. Accessors: // PURPOSE: To tell the current turn. int getTurn () const { return(turn_); } // VI. Mutators: // VII. Methods that do the main and misc. work of class: // PURPOSE: To consolidate the Coin instances of '*donorPursePtr' into // '*this' one. // (Note to the professional C++ coders: Yeah, I know it is better to use // call-by-reference. I use pointers for consistency.) // PUT CODE 3 PLACES IN HERE . . . I WONDER WHERE? void consolidate (Purse* donorPursePtr ) { // I. Application validity check: // II. Transfer the wealth: while (getTurn() != donorPursePtr->getIndex()) { printf ("%s: \"I want candy! Let's put our money together!\" ", donorPursePtr->getOwnerNameCPtr() ); } while (donorPursePtr->getNumCoins() > 0) { addToBack(donorPursePtr->removeFromFront()); } printf ("%s: \"I added my money.\" ", donorPursePtr->getOwnerNameCPtr() ); turn_--; // III. Finished: } }; //-- Global vars: --// // PURPOSE: To represent the shared, thread-safe Purse instance. CommonPurse sharedPurse; //-- Main functions: --// // PURPOSE: To add the Coin instances in '*(Purse*)vPtr' to 'sharedPurse'. // Returns 'NULL'. void* consolidate (void* vPtr ) { Purse* pursePtr = NULL; // CHANGE THAT NULL // YOUR CODE HERE return(NULL); } // PURPOSE: To have the children add their money to 'sharedPurse', and // then attempt to buy the candy. Ignores parameters. Returns // 'EXIT_SUCCESS' to OS. int main () { // I. Application validity check: // II. Try to buy candy: // II.A. Initialize data-structures: Purse* pursePtrArray[NUM_CHILDREN]; srand(getpid()); for (int i = 0; i print(); } // II.B. Consolidate the money: // YOUR CODE HERE TO START THREADS // II.C. Close program down: // YOUR CODE HERE TO WAIT FOR THREADS for (int i = 0; i = CANDY_COST) { printf("Yay! We can afford the candy!\" "); } else { printf("Time to beg mom for more money!\" "); } // III. Finished: return(EXIT_SUCCESS); } 

A. Finish Purse:

Purse must implement a linked list of Coin instances using the Coin methods getNextPtr() and setNextPtr(). (No cheating and using C++ containers like std::list, std::vector, etc.)

1. Give class Purse 3 member variables:

-A Coin* to point to the beginning of the list.

-A Coin* to point to the end of the list.

-An int that keeps track of the length of the list.

2. Initialize your variables in the constructor.

3. Get rid of your list in the destructor method: ~Purse(). In C one gets memory with malloc() and gives it back with free(). However, in C++ one gets memory and builds an instance of an object with new, and one dismantles the instance with delete(). Please have a local variable like coinPtr and say delete(coinPtr) for each Coin in the list.

4. Make getValue() loop thru the Coin instances. It should sum all the getDenomination() values of the Coin instances, and return() the sum.

5. Make getNumCoins() returns the how many Coin instances are in the list.

6. Make addToBack() add coinPtr to the back of the list. It should also increment your list-length variable.

7. Make removeFromFront() remove the first Coin instance from the linked list. It should also decrement your list-length variable, and return() the address of the first Coin.

B. Make it multi-threaded:

1. In main() you will need an array of NUM_CHILDREN pthread_t instances for the bee hive threads.

- In section II.B declare your array variable. Have a loop that starts all NUM_CHILDREN threads. Each thread should run consolidate(), and pass the address of the corresponding Purse as an argument.

- In section II.C wait for all child threads to finish.

2. In consolidate(), argument vPtr comes in pointing to a Purse. Set pursePtr equal to vPtr (you will need to cast it). The only thing the function needs to do is run sharedPurse.consolidate(pursePtr).

3. To make it thread-safe you will have to add some mutex(es) and condition(s).

-You need to protect access to the linked list and turn_ in CommonPurse method consolidate().

-It needs one pthread_mutex_t variable and an array of NUM_CHILDREN+1 pthread_cond_t instances.

-Initialize those variables in CommonPurse().

-Destroy those variables in ~CommonPurse().

-Use them in consolidate() in CommonPurse. Where does the critical section begin? Where does the critical section end?

Note: all threads should wait on the pthread_cond_t with index donorPursePtr->getIndex()+1. Also, all threads should signal the pthread_cond_t with index donorPursePtr->getIndex().

Questions:

How well did your program work before making it thread safe?

How well did your program work after making it thread safe?

Sample ouput:

image text in transcribed

Please show screenshots of output!

Thank you!

$./buyTheCandy Alice has 4 coins worth 41 cents. Bob has 4 coins worth 50 cents. Cathy has 4 coins worth 16 cents. David has 4 coins worth 50 cents. Bob: "I want candy! Let's put our money together!" Cathy: "I want candy! Let's put our money together!" David: "I added my money." Alice: "I want candy! Let's put our money together!" Cathy: "I added my money." Bob: "I added my money. Alice: "I added my money." All: "We have 157 cents. Yay! We can afford the candy!" $./buyTheCandy Alice has 4 coins worth 12 cents. Bob has 4 coins worth 36 cents. Cathy has 4 coins worth 8 cents. David has 4 coins worth 16 cents. Alice: "I want candy! Let's put our money together!" Cathy: "I want candy! Let's put our money together!" Bob: "I want candy! Let's put our money together!" David: "I added my money." Cathy: "I added my money." Bob: "I added my money. Alice: "I added my money." All: "We have 72 cents. Time to beg mom for more money!" \$./buyTheCandy Alice has 4 coins worth 37 cents. Bob has 4 coins worth 22 cents. Cathy has 4 coins worth 80 cents. David has 4 coins worth 21 cents. Alice: "I want candy! Let's put our money together!" Bob: "I want candy! Let's put our money together!" David: "I added my money." Cathy: "I added my money." Bob: "I added my money. Alice: "I added my money." All: "We have 160 cents. Yay! We can afford the candy

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Databases Demystified

Authors: Andrew Oppel

1st Edition

0072253649, 9780072253641

More Books

Students also viewed these Databases questions

Question

LO2 Explain the major laws governing employee compensation.

Answered: 1 week ago

Question

Define span of management or define span of control ?

Answered: 1 week ago

Question

What is meant by formal organisation ?

Answered: 1 week ago

Question

What is meant by staff authority ?

Answered: 1 week ago

Question

Discuss the various types of policies ?

Answered: 1 week ago

Question

What is the difference between Needs and GAP Analyses?

Answered: 1 week ago

Question

What are ERP suites? Are HCMSs part of ERPs?

Answered: 1 week ago