Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Overview: There is a farmer who wants honey. There are 4 bee hives that are willing to give honey, but want flowers in return. Cut-and-paste

  1. Overview:

    There is a farmer who wants honey. There are 4 bee hives that are willing to give honey, but want flowers in return.
  2. Cut-and-paste the following:

    /*-------------------------------------------------------------------------* *--- ---* *--- hungryBees.cpp ---* */ //--- Header file inclusion: ---// #include #include #include #include #include #include //--- Definition of constants: ---// // PURPOSE: To tell how many flowers each bee hive must visit. const int NUM_FLOWERS_TO_COLLECT = 5; // PURPOSE: To tell the number of bee hives that exist. const int NUM_BEE_HIVES = 4; // PURPOSE: To hold the names of the flowers: const char* FLOWER_NAME_ARRAY[] = { "Jasmine", "Daffodil", "Daisy", "Dandelion", "Venus fly trap", "Tumbleweed", "Kudzu", "Poison Ivy" }; // PURPOSE: To tell how many flower names there are. const size_t NUM_FLOWER_NAMES= sizeof(FLOWER_NAME_ARRAY)/sizeof(const char*); //--- Definition of classes and structs: ---// // PURPOSE: To represent a flower. class Flower { // I. Member vars: // PURPOSE: To hold address of the name of the flower as a C-string. const char* nameCPtr_; // PURPOSE: To hold the address of the Flower instance after '*this' one, // or 'NULL' if there is no such Flower. Flower* nextPtr_; // II. Disallowed auto-generated methods: // No copy constructor: Flower (const Flower&); // No copy assignment op: Flower& operator= (const Flower&); protected : // III. Protected methods: public : // IV. Constructor(s), assignment op(s), factory(s) and destructor: // PURPOSE: To make '*this' a stand-alone Flower instance with a randomly- // chosen name. No parameters. No return value. Flower () : nameCPtr_(FLOWER_NAME_ARRAY[rand() % NUM_FLOWER_NAMES] ), nextPtr_(NULL) { } // PURPOSE: To release the resources of '*this'. No parameters. No // return value. ~Flower () { } // V. Accessors: // PURPOSE: To return the name of the flower. No parameters. const char* getNameCPtr () const { return(nameCPtr_); } // PURPOSE: To return the address of the Flower instance after '*this' one, // or 'NULL' if there is no such Flower. Flower* getNextPtr () const { return(nextPtr_); } // VI. Mutators: // PURPOSE: To note that the next flower in the list has address // 'newNextPtr'. No return value. void setNextPtr (Flower* newNextPtr ) { nextPtr_ = newNextPtr; } // VII. Methods that do main and misc work of class: }; class Garden { // I. Member vars: // YOUR MEMBER VARS HERE // II. Disallowed auto-created methods: // No copy constructor: Garden (const Garden&); // No copy assignment op: Garden& operator= (const Garden&); protected : // III. Protected methods: public : // IV. Constructor(s), assignment op(s), factory(s) and destructor: // PURPOSE: To initialize '*this' to an empty garden. No parameters. // No return value. Garden () { // INITIALIZE HERE } // PURPOSE: To release the resources of '*this'. No parameters. // No return value. ~Garden () { // GET RID OF LIST HERE } // V. Accessor(s): // PURPOSE: To hold length of '*this' list. int getNumFlowers () const { return(0); /* CHANGE THAT 0 */} // VI. Mutator(s): // VII. Methods that do main and misc. work of class: // PURPOSE: To add the Flower with address 'flowerPtr' at the back of // '*this' Garden of Flower instances. No return value. void store (Flower* flowerPtr ) { // ADD TO LIST HERE } // PURPOSE: To print this list of Flower instances in '*this' Garden. // No parameters. No return value. void print () { // ADD TO LIST HERE } }; struct Hive { std::string name_; Garden* gardenPtr_; Hive () : name_(""), gardenPtr_(NULL) { } ~Hive () { delete(gardenPtr_); } const char* getNameCPtr () const { return(name_.c_str()); } }; //--- Definition of global vars: ---// // PURPOSE: To hold the address of the flower offered by the farmer. // or to hold 'NULL' if there is no such Flower. Flower* availableFlowerPtr = NULL; // PURPOSE: To tell how much honey has been produced by the bee hives. int honey = 0; // YOUR CODE HERE to add global vars to control access to availableFlowerPtr and honey: //--- Definition of main functions: ---// // PURPOSE: To be the function run by the bee hive threads. 'vPtr' points // to an instance of 'Hive'. Returns 'NULL'. void* hive (void* vPtr ) { // I. Application validity check: // II. Get the flowers: // II.A. Initialize local vars: Hive* hivePtr = NULL; // CHANGE THAT NULL Garden* gardenPtr = NULL; // CHANGE THAT NULL // II.B. Each iteration obtains another Flower instance for the graden // of Hive '*hivePtr': while (gardenPtr->getNumFlowers() < NUM_FLOWERS_TO_COLLECT) { // YOUR CODE HERE: Make access to avaialbleFlowerPtr thread-safe while (availableFlowerPtr == NULL) { printf("%s: \"Hey! No flowers, no honey!\" ",hivePtr->getNameCPtr()); } printf("%s: \"A %s! Sure we will take that!\" ", hivePtr->getNameCPtr(),availableFlowerPtr->getNameCPtr() ); gardenPtr->store(availableFlowerPtr); availableFlowerPtr = NULL; // Leave this outside critical section: sleep(rand() % 3); // Please leave this OUT of the critical section } // II.C. Add to the honey when have enough flowers: printf("%s \"Finally, enough flowers to make some honey.\" ", hivePtr->getNameCPtr() ); // YOUR CODE HERE: Make incrementing honey thread-save honey++; // III. Finished: return(NULL); } // PURPOSE: To be the function run by the farmer thread. 'vPtr' is ignored. // Returns 'NULL'. void* farmer (void* vPtr) { // I. Application validity check: // II. Give flowers: // II.A. Each iteration creates and gives another Flower instance // until there is sufficient honey: while (true) { // YOUR CODE HERE: Make access to honey thread-safe if (honey >= NUM_BEE_HIVES) { break; } printf("Farmer: \"I have to gather *more* flowers?!?\" "); // YOUR CODE HERE: Make access to availableFlowerPtr thread-safe while (availableFlowerPtr != NULL) { printf("Farmer: \"Hey, you said you wanted" " a flower, come and take it.\" " ); } availableFlowerPtr = new Flower; printf("Farmer: \"Okay here is another flower: a %s\" ", availableFlowerPtr->getNameCPtr() ); // Leave this outside critical section: sleep(rand() % 3); // Please leave this OUT of the critical section } // III. Finished: printf("Farmer \"I *finally* got my honey!\" "); return(NULL); } // PURPOSE: To run the program. Ignores command line arguments. Returns // 'EXIT_SUCCESS' to OS. int main () { // I. Application validity check: // II. Have the farmer give Flower instances until sufficient honey // has been obtained: // II.A. Randomize random number generator: srand(getpid()); // II.B. Initialize global vars: Hive hiveArray[NUM_BEE_HIVES]; // Add something here? // II.C. Make threads: // II.C.1. Make bee hive threads: for (int i = 0; i < NUM_BEE_HIVES; i++) { hiveArray[i].name_ = std::string("Hive ") + (char)('A'+i); hiveArray[i].gardenPtr_ = new Garden; // Add something here? } // II.C.2. Make farmer thread: // Add something here? // II.D. Wait for child threads: // II.D.1. Wait for bee hive threads: for (int i = 0; i < NUM_BEE_HIVES; i++) { // Add something here? printf("%s has: ",hiveArray[i].getNameCPtr()); hiveArray[i].gardenPtr_->print(); } // II.D.2. Wait for farmer thread: // Add something here? // II.E. Get rid of global vars: // Add something here? // III. Finished: return(EXIT_SUCCESS); } 
  3. Finish Garden:

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

    1. Give class Garden 3 member variables:
      • A Flower* to point to the beginning of the list.
      • A Flower* 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: ~Garden(). 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 flowerPtr and say delete(flowerPtr) for each Flower in the list.
    4. Make getNumFlowers() return the how many Flower instances are in the list.
    5. Make store() add new Flower instance flowerPtr to the end of the list.
    6. Make print() print the Flower instances in the list.
  4. Make it multi-threaded:

    1. In main() you will need a single pthread_t for the farmer thread, and an array of NUM_BEE_HIVES pthread_t instances for the bee hive threads.
      1. Declare your variables in section II.B.
      2. Start your threads in section II.C. The bee hive threads should run hive() with the address of hiveArray[i] passed to them. The farmer thread should run farmer(). Just pass NULL as the argument to farmer().
      3. In section II.D wait for all child threads to finish.
    2. In hive(), argument vPtr comes in pointing to a Hive. Set hivePtr equal to vPtr (you will need to cast it), and set gardenPtr equal to the address of the Garden owned by the Hive. (See struct Hive.)
    3. Now run it!
  5. Make it thread-safe:

    Congratulations! If you got this far you have made it multi-threaded, but not thread-safe. To make it thread-safe you will have to add some mutex(es) and condition(s).

    You need to protect access to two variables:

    • availableFlowerPtr, under Definition of global vars:. This one acts like a one-element buffer.
      • The farmer thread has to wait while it has a non-NULL value ("is-full").
      • The bee hive threads have to wait while it has a NULL value ("is-empty").
    • honey, also under Definition of global vars:. Unlike availableFlowerPtr, there is no need to wait to use this variable.

    Stop! Think! What needs mutexes? What needs conditions?

    1. Declare your variables globally in the Definition of global vars: section
    2. Initialize those variables in main() in section II.B.
    3. Destroy those variables in main() in section II.E.
    4. Use them in farmer to protect access to both honey and availableFlowerPtr.
    5. Use them in hive to protect access to both availableFlowerPtr and honey.

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

Modern Database Management

Authors: Heikki Topi, Jeffrey A Hoffer, Ramesh Venkataraman

13th Edition

0134773659, 978-0134773650

More Books

Students also viewed these Databases questions

Question

What is the purpose of a customized benefits plan?

Answered: 1 week ago

Question

What are topics included within employee services?

Answered: 1 week ago