hungryBees.cpp (100 Points)There is a farmer who wants honey.Overview:There are 4 bee hives that are willing to give honey, but want flowers in return.Thefarmerthread runs a loop that only stops...

2 answer below »


hungryBees.cpp (100 Points)
There is a farmer who wants honey.



  1. Overview:


  2. There are 4 bee hives that are willing to give honey, but want flowers in return.



  • Thefarmerthread runs a loop that only stops when:honey >= NUM_BEE_HIVES. Until then, the farmer patiently makes another flower withnew Flowerand gives it to one of the bee hives.

  • Thebee hivethreads collectFlowerinstances and add them to their own personalGardeninstances. When theirGardeninstances haveNUM_FLOWERS_TO_COLLECTflowers, then they increment thehoneycounter for the farmer.



  1. Cut-and-paste the following:


/*-------------------------------------------------------------------------*

*------*

*---hungryBees.cpp---*

*------*

*--- This file defines a C-ish C++ program that exercises---*

*---knowledge of POSIX threads and linked list manipulation.---*

*------*

*--------------------------------------*

*------*

*---Version 1a ---*

*------*

*-------------------------------------------------------------------------*/


//---Header file inclusion:---//


#include
#include
#include
#include
#include
#include




//---Definition of constants:---//


// PURPOSE: To tell how many flowers each bee hive must visit.
const intNUM_FLOWERS_TO_COLLECT

= 5;


// PURPOSE: To tell the number of bee hives that exist.
const intNUM_BEE_HIVES= 4;


// PURPOSE: To hold the names of the flowers:
const char* FLOWER_NAME_ARRAY[]

= { "Jasmine",

"Daffodil",

"Stinging Nettle",

"Dandelion",

"Venus fly trap",

"Tumbleweed",

"Kudzu",

"Poison Ivy"

};


// PURPOSE: To tell how many flower names there are.
const size_tNUM_FLOWER_NAMES= sizeof(FLOWER_NAME_ARRAY)/sizeof(const char*);




//--- Definition of classes and structs:---//


// PURPOSE: To represent a flower.
classFlower
{

// 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.

voidsetNextPtr(Flower*newNextPtr

)

{ nextPtr_ = newNextPtr; }



// VII. Methods that do main and misc work of class:


};


classGarden
{

// 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.

intgetNumFlowers()

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.

voidstore(Flower*flowerPtr

)

{

// ADD TO LIST HERE

}



// PURPOSE: To print this list of Flower instances in '*this' Garden.

//No parameters. No return value.

voidprint()

{

// ADD TO LIST HERE

}


};




structHive
{

std::stringname_;

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.
inthoney= 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() <>

{

// YOUR CODE HERE: Make access to availbleFlowerPtr thread-safe



while (availableFlowerPtr == NULL)

{

printf("%s: "Hey! No flowers, no honey!"n",hivePtr->getNameCPtr());

}



printf("%s: "A %s! Sure we will take that!"n",

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."n",

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?!?"n");



// 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."n"

);

}



availableFlowerPtr= new Flower;

printf("Farmer: "Okay here is another flower: a %s"n",

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!"n");

return(NULL);
}




// PURPOSE: To run the program. Ignores command line arguments. Returns
//'EXIT_SUCCESS' to OS.
intmain()
{

// 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:

HivehiveArray[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;="">

{

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;="">

{

// Add something here?

printf("%s has:n",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);
}





  1. FinishGarden:

  2. Gardenmust implement a linked list ofFlowerinstances using theFlowermethodsgetNextPtr()andsetNextPtr(). (No cheating and using C++ containers likestd::list,std::vector, etc.)

  3. Giveclass Garden3 member variables:



  • AFlower*to point to the beginning of the list.

  • AFlower*to point to the end of the list.

  • Anintthat keeps track of the length of the list.



  1. Initialize your variables in the constructor.

  2. Get rid of your list in thedestructormethod:~Garden(). In C one gets memory withmalloc()and gives it back withfree(). However, in C++ one gets memory and builds an instance of an object withnew, and one dismantles the instance withdelete().

  3. Please have a local variable likeflowerPtrand saydelete(flowerPtr)for eachFlowerin the list.

  4. MakegetNumFlowers()return the how manyFlowerinstances are in the list.

  5. Makestore()add newFlowerinstanceflowerPtrto the end of the list.

  6. Makeprint()print theFlowerinstances in the list.

  7. Make it multi-threaded:

  8. Inmain()you will need a singlepthread_tfor the farmer thread, and an array ofNUM_BEE_HIVESpthread_tinstances for the bee hive threads.

  9. Declare your variables in sectionII.B.

  10. Start your threads in sectionII.C. The bee hive threads should runhive()with the address ofhiveArray[i]passed to them. The farmer thread should runfarmer(). Just passNULLas the argument tofarmer().

  11. In sectionII.Dwait for all child threads to finish.

  12. Inhive(), argumentvPtrcomes in pointing to aHive. SethivePtrequal tovPtr(you will need to cast it), and setgardenPtrequal to the address of theGardenowned by the Hive. (Seestruct Hive.)


  13. Now run it!

  14. Make it thread-safe:

  15. Congratulations! If you got this far you have made itmulti-threaded, but notthread-safe.

  16. To make it thread-safe you will have to add somemutex(es)andcondition(s).

  17. You need to protect access to two variables:



  • availableFlowerPtr, underDefinition of global vars:. This one acts like a one-element buffer.

  • The farmer thread has to wait while it has a non-NULLvalue ("is-full").

  • The bee hive threads have to wait while it has aNULLvalue ("is-empty").

  • honey, also underDefinition of global vars:. UnlikeavailableFlowerPtr, there is no need to wait to use this variable.




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

  2. Declare your variables globally in theDefinition of global vars:section

  3. Initialize those variables inmain()in sectionII.B.

  4. Destroy those variables inmain()in sectionII.E.

  5. Use them infarmerto protect access to bothhoneyandavailableFlowerPtr.

  6. Use them inhiveto protect access to bothavailableFlowerPtrandhoney.

  7. Questions:


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


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

  10. Sample output:


$ ./hungryBees

Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Dandelion"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Hey, you said you wanted a flower, come and take it."
Hive A: "A Dandelion! Sure we will take that!"
Hive C: "Hey! No flowers, no honey!"
Hive B: "Hey! No flowers, no honey!"
Hive D: "Hey! No flowers, no honey!"
Farmer: "Okay here is another flower: a Stinging Nettle"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Hey, you said you wanted a flower, come and take it."
Hive C: "A Stinging Nettle! Sure we will take that!"
Farmer: "Okay here is another flower: a Dandelion"
Hive B: "A Dandelion! Sure we will take that!"
Hive B: "Hey! No flowers, no honey!"
Hive A: "Hey! No flowers, no honey!"
Hive C: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Jasmine"
Hive D: "A Jasmine! Sure we will take that!"
Hive D: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Poison Ivy"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Hey, you said you wanted a flower, come and take it."
Hive B: "A Poison Ivy! Sure we will take that!"
Farmer: "Okay here is another flower: a Daffodil"
Hive A: "A Daffodil! Sure we will take that!"
Hive A: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Hive B: "Hey! No flowers, no honey!"
Farmer: "Okay here is another flower: a Daffodil"
Hive C: "A Daffodil! Sure we will take that!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Poison Ivy"
Hive D: "A Poison Ivy! Sure we will take that!"
Hive D: "Hey! No flowers, no honey!"
Hive C: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Stinging Nettle"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Hey, you said you wanted a flower, come and take it."
Hive A: "A Stinging Nettle! Sure we will take that!"
Farmer: "Okay here is another flower: a Stinging Nettle"
Hive B: "A Stinging Nettle! Sure we will take that!"
Hive A: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Hive B: "Hey! No flowers, no honey!"
Farmer: "Okay here is another flower: a Daffodil"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Hey, you said you wanted a flower, come and take it."
Hive D: "A Daffodil! Sure we will take that!"
Farmer: "Okay here is another flower: a Tumbleweed"
Hive C: "A Tumbleweed! Sure we will take that!"
Hive D: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Tumbleweed"
Hive A: "A Tumbleweed! Sure we will take that!"
Hive C: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Poison Ivy"
Hive A: "A Poison Ivy! Sure we will take that!"
Hive A "Finally, enough flowers to make some honey."
Hive B: "Hey! No flowers, no honey!"
Hive A has:

Dandelion

Daffodil

Stinging Nettle

Tumbleweed

Poison Ivy
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Poison Ivy"
Hive D: "A Poison Ivy! Sure we will take that!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Dandelion"
Hive C: "A Dandelion! Sure we will take that!"
Hive D: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Daffodil"
Hive C: "A Daffodil! Sure we will take that!"
Hive C "Finally, enough flowers to make some honey."
Hive B: "Hey! No flowers, no honey!"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Venus fly trap"
Hive D: "A Venus fly trap! Sure we will take that!"
Hive D "Finally, enough flowers to make some honey."
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Okay here is another flower: a Poison Ivy"
Farmer: "I have to gather *more* flowers?!?"
Farmer: "Hey, you said you wanted a flower, come and take it."
Hive B: "A Poison Ivy! Sure we will take that!"
Hive B: "Hey! No flowers, no honey!"
Farmer: "Okay here is another flower: a Daffodil"
Hive B: "A Daffodil! Sure we will take that!"
Hive B "Finally, enough flowers to make some honey."
Hive B has:

Dandelion

Poison Ivy

Stinging Nettle

Poison Ivy

Daffodil
Hive C has:

Stinging Nettle

Daffodil

Tumbleweed

Dandelion

Daffodil
Hive D has:

Jasmine

Poison Ivy

Daffodil

Poison Ivy

Venus fly trap
Farmer "I *finally* got my honey!"
Answered 1 days AfterOct 31, 2022

Answer To: hungryBees.cpp (100 Points)There is a farmer who wants honey.Overview:There are 4 bee hives that are...

Robert answered on Nov 02 2022
43 Votes
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here