Yes this is a HW assignment, NO I am not posting looking for answer, just a beginner that needs some guidance.
1.Create a structure Coin and a class Purse.
A coin has a name and monetary value. Choose your way to implement a coin, but provide a way to check that two coins have equal names and monetary values.
A purse holds a collection of coins.
Make a Purse constructor to construct an empty purse and the following methods of the class Purse:
a. Add a number of instances of a coin to the purse.
Parameters: the coin to add and how many of it.
b. Count the number of coins in the purse that match a given coin.
Parameter: the coin to match.
Return value: the number of coins equal to the coin to match.
c. Get the total value of the coins in the purse.
Return the sum of all coin values.
d. Count the number of coins in the purse.
Return the number of coins.
2. Create a console application in which the main function will initialize an array of 10 purses and will start 10 threads working simultaneously with these purses without causing inconsistent states. Initially set up the purses with the same coins in each purse. The main function will wait for all threads to finish and then finish itself.
3. Each of the threads should have its own purse, from which it will take money and place in other purses. For this purpose it will repeatedly select a target purse at random and coins to move in the target purse. If the needed coins are not available at the moment, it should wait until they become available and do the move. Since the move of coins from one purse to another involves taking the coins out of one purse and putting them in another purse, each time select at random which operation to do first, and have a small delay between the operations, to allow for race conditions. From time to time each thread will sum up the coins of each denomination in all purses. Pay attention to the readability of the program output. If the threads are properly synchronized, the total number of coins of each denomination should be constant.
4. Provide synchronization using locks. Clearly identify with comments the points in the programs at which you obtain and release the locks, so that it is easy to find these points and test the programs with and without synchronization.
5. Test your programs with and without synchronization and note the results in the test report. Reason about the possibility of your synchronized programs to create deadlocks. If your analysis shows the possibility of a deadlock, provide test cases that could lead to deadlocks and note the results in the test report. Then change the necessary settings (initial coins, maximum numbers to move, associations between threads and purses, etc. to create a program in which a deadlock cannot occur. If your analysis shows that deadlock is impossible, change the original settings to be able to illustrate deadlocks, record the changes in the test report, and provide test cases that can lead to a deadlock. In all cases record your reasoning, the experiments, the expected and the actual results in the test report. Provide the source code before and after the changes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
//purseTest.cpp using namespace System;
#include "Purse.h"
int main() {
Purse^ myPurse = gcnew Purse();
Thread^ addNickels = gcnew Thread(gcnew ParameterizedThreadStart(myPurse, &Purse::addNickels));
Thread^ addQuarters = gcnew Thread(gcnew ParameterizedThreadStart(myPurse, &Purse::addQuarters));
Thread^ remove = gcnew Thread(gcnew ParameterizedThreadStart(myPurse, &Purse::removeCoin));
Thread^ count = gcnew Thread(gcnew ThreadStart(myPurse, &Purse::getTotal));
int^ nickles = 5;
double^ size = .05;
addNickels->Start(dynamic_cast<Object^>(nickles));
addQuarters->Start(dynamic_cast<Object^>(nickles));
remove->Start(dynamic_cast<Object^>(size));
count->Start();
count = gcnew Thread(gcnew ThreadStart(myPurse, &Purse::getTotal));
Thread::Sleep(200);
count->Start();
Console::ReadLine();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
//purse.cpp using namespace System;
#include "Purse.h"
#include <random>
/**
Constructs an empty purse.
*/
Purse::Purse()
{
nickels = 0;
dimes = 0;
quarters = 0;
}
/**
Add nickels to the purse.
@param count the number of nickels to add
*/
void Purse::addNickels(Object^ count)
{
for (int i = 1; i <= static_cast<int>(count); i++){
Monitor::Enter(this);
nickels = nickels += 1;
Console::WriteLine("{0} nickles added",i);
Thread::Sleep(rand() % 20);
Monitor::Exit(this);
}
}
/**
Add dimes to the purse.
@param count the number of dimes to add
*/
void Purse::addDimes(Object^ count){
for (int i = 1; i <= static_cast<int>(count); i++){
Monitor::Enter(this);
dimes = dimes += 1;
Console::WriteLine("{0} dimes added", i);
Thread::Sleep(rand() % 20);
Monitor::Exit(this);
}
}
/**
Add quarters to the purse.
@param count the number of quarters to add
*/
void Purse::addQuarters(Object^ count)
{
for (int i = 1; i <= static_cast<int>(count); i++){
Monitor::Enter(this);
quarters += 1;
Console::WriteLine("{0} Quarters added", i);
Thread::Sleep(rand() % 20);
Monitor::Exit(this);
}
}
void Purse::removeCoin(Object^ val){
if (static_cast<double>(val) == NICKEL_VALUE){
Monitor::Enter(this);
nickels -= 1;
Console::WriteLine("nickle removed");
Thread::Sleep(rand() % 20);
Monitor::Exit(this);
}
else if (static_cast<double>(val) == DIME_VALUE){
Monitor::Enter(this);
dimes -= 1;
Console::WriteLine("dime removed");
Thread::Sleep(rand() % 20);
Monitor::Exit(this);
}
else if (static_cast<double>(val) == QUARTER_VALUE){
Monitor::Enter(this);
quarters -= 1;
Console::WriteLine("quarter removed");
Thread::Sleep(rand() % 20);
Monitor::Exit(this);
}
else{
Console::WriteLine("not a valid donomination");
}
}
/**
Get the total value of the coins in the purse.
@return the sum of all coin values
*/
void Purse::getTotal()
{
double total = 0;
Monitor::Enter(this);
total += nickels* NICKEL_VALUE;
total += dimes* DIME_VALUE;
total += quarters* QUARTER_VALUE;
Thread::Sleep(rand() % 20);
Console::WriteLine("{0} is the total amount", total);
Monitor::Exit(this);
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
//purse.h using namespace System;
using namespace System::Threading;
ref class Purse
{
public:
/**
Constructs an empty purse.
*/
Purse();
/**
Add nickels to the purse.
@param count the number of nickels to add
*/
void addNickels(Object^ count);
/**
Add dimes to the purse.
@param count the number of dimes to add
*/
void addDimes(Object^ count);
/**
Add quarters to the purse.
@param count the number of quarters to add
*/
void addQuarters(Object^ count);
//removes one coin of the specifed denomination
void removeCoin(Object^ count);
/**
Get the total value of the coins in the purse.
@return the sum of all coin values
*/
void getTotal();
private:
static const double NICKEL_VALUE = 0.05;
static const double DIME_VALUE = 0.1;
static const double QUARTER_VALUE = 0.25;
int nickels;
int dimes;
int quarters;
};//ref class Purse
|