///////////////////////////////////////////////////////////////////////////////////// TODO:: Add any needed includes///////////////////////////////////////////////////////////////////////////////////#include <iostream>#include <ostream>#include <mutex>#include <random>#include <vector>
// Include file and line numbers for memory leak detection forvisual studio in debug mode#if defined _MSC_VER && defined _DEBUG #include <crtdbg.h> #define new new(_NORMAL_BLOCK, __FILE__,__LINE__) #define ENABLE_LEAK_DETECTION()_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF)#else #define ENABLE_LEAK_DETECTION()#endif
class UniformRandInt{public: void Init(int min, int max) { // Seed our random numbergenerator with a non-deterministic random value. If no suchcapabilities exist then // the number will bepulled from a pseudo random number generator. randEngine.seed(randDevice());
// We want to generatevalues in the range of [min, max] (inclusive) with a uniformdistribution. distro =std::uniform_int_distribution<int>(min, max); }
int operator()() { returndistro(randEngine); }
private: std::random_device randDevice; std::mt19937 randEngine; std::uniform_int_distribution<int>distro;};
struct ThreadStruct{ int id; // thread number UniformRandInt myRand; // random number generator for thisthread /////////////////////////////////////////////////////////////////////////////////// // TODO:: Any new data to pass to thread shouldbe put here /////////////////////////////////////////////////////////////////////////////////// };
///////////////////////////////////////////////////////////////////////////////////// Prompts the user to press enter and waits for user input///////////////////////////////////////////////////////////////////////////////////void Pause(){ printf("Press enter to continue\n"); getchar();}
////////////////////////////////////////////////////////////////////////////////////// TODO:: Create a function to process (in this case just print)the 'work' // generated by the Joinable and Detached threads that werecreated in main. The // purpose of this function is to delay the printing of'work' until it's been generated. // You must also print out the thread ID along with the workvalue.//// Note: You are required to use a std::promise to implement thislogic.////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////// Entry point for joinable threads. //// Arguments:// threadData - Pointer to the thread specific data///////////////////////////////////////////////////////////////////////////////////void JoinableThreadEntrypoint(ThreadStruct *threadData){ //////////////////////////////////////////////////////////////////////////////////// // TODO:: Create a joinable thread to print thevalue of 'work' once it's generated. // The printer (or "process work") threadMUST be created before 'work' is initialized and it must not // print until 'work' has been generatedby this thread. // // Note: You are required to use a std::promiseto implement the printing logic. ////////////////////////////////////////////////////////////////////////////////////
int workLimit = (threadData->id + 1) +(threadData->myRand()); int work = 0;
// Performs some arbitrary amount ofwork. printf("START: Joinable Thread %d, startinglimit = %d\n", threadData->id, workLimit); for (int i = 0; i < workLimit; i +=(threadData->id + 1)) { work++; }
printf("FINISH: Joinable thread %d, finishedwith value %d\n", threadData->id, work);
/////////////////////////////////////////////////////////////////////////////////// // TODO:: The 'work' has been generated and theprinting thread should be waiting // on the promised work to be set. Set itnow so the printing thread can resume. ///////////////////////////////////////////////////////////////////////////////////}
///////////////////////////////////////////////////////////////////////////////////// Entry point for detached threads. //// Arguments:// threadData - Pointer to the thread specific data///////////////////////////////////////////////////////////////////////////////////void DetachedThreadEntrypoint(ThreadStruct *threadData){ //////////////////////////////////////////////////////////////////////////////////// // TODO:: Create a joinable thread to print thevalue of 'work' once it's generated. // The printer thread MUST be createdbefore 'work' is initialized and it must not // print until 'work' has been generatedby this thread. // // Note: You are required to use a std::promiseto implement the printing logic. ////////////////////////////////////////////////////////////////////////////////////
int workLimit = (threadData->id + 1) +(threadData->myRand()); int work = 0;
printf("START: Detached Thread %d, startinglimit = %d\n", threadData->id, workLimit); while(true) { //////////////////////////////////////////////////////////////////////////////// // TODO:: Break out of thework loop in a thread safe way. // (HINT: thread safe means that onlyONE thread should be check or modifying // shared data at a time) ///////////////////////////////////////////////////////////////////////////////////
// Performs some arbitraryamount of work. for (int i = 0; i <workLimit; i += (threadData->id + 1)) { work++; } } printf("FINISH: Detached thread %d, finishedwith value %d\n", threadData->id, work);
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Set the std::promise's value and waitfor the printer thread to finish. ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Let main know there's one less threadrunning. ///////////////////////////////////////////////////////////////////////////////////}
int main(int argc, char **argv){ ENABLE_LEAK_DETECTION();
if (argc != 2) { fprintf(stderr, "Usage:ThreadTypes threadCount\n\n"); fprintf(stderr,"Arguments:\n"); fprintf(stderr, " threadCount Number of joinable and detached threads to \n"); fprintf(stderr, " create. \n"); Pause(); return 1; }
int totalThreadCount = 2 *atoi(argv[1]); if(totalThreadCount < 0) { fprintf(stderr, "Error: Allarguments must be positive integer values.\n"); Pause(); return 1; }
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Declare your variables here ///////////////////////////////////////////////////////////////////////////////////
ThreadStruct *perThreadData = newThreadStruct[totalThreadCount]; printf("Main thread starting %d thread(s)\n",totalThreadCount); for(int i = totalThreadCount - 1; i >= 0;i--) { perThreadData.id =i; perThreadData.myRand.Init(0, 100);
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Initialize anyadditional per-thread data and create the threads. If 'i' is // odd then the threadmust execute the 'detached' logic in a detached state,otherwise // the thread mustexecute the 'joinable' logic. /////////////////////////////////////////////////////////////////////////////////// }
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Wait for all joinable threads tocomplete ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// // TODO:: let detached threads know they need toshut down using the flag you // created in the thread structure. Youmay only set the flag once here (you should // not have more than one flag) and itmust be in a thread safe manner. ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Wait for all detached threads tofinish without using a busy-wait loop. // You must wait for the number ofthreads to change before checking again to avoid // wasting CPU cycles. // (HINT: Remember there is a specificobject that can Wait for a Condition) ///////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Cleanup /////////////////////////////////////////////////////////////////////////////////// Pause(); return 0;}
/////////////////////////////////////////////////////////////////////////////////// // TODO:: Add any needed includes /
-
- Site Admin
- Posts: 899603
- Joined: Mon Aug 02, 2021 8:13 am