// // Simple program demonstrating the use of threads. Each thread executes // a loop similar to what is described in the mutual-exclusion problem. // // Command-line arguments are P (number of threads) and N (number of times // each should execute its loop). // #include #include #include #include // has exit(), etc. #include // has usleep() #include // has pthread_ routines using namespace std; // C++ "standard" namespace // declaration for function to be executed by each thread void * threadFcn(void * threadArg); // ---- Shared variables ---- int N; // trips through loop const int CR_DELAY = 10; // maximum delay in critical region const int NON_CR_DELAY = 100; // maximum delay in non-critical region // ---- Main program ---- int main(int argc, char* argv[]) { if (argc < 3) { cerr << "Usage: " << argv[0] << " numThreads tripsThroughLoop\n"; exit(EXIT_FAILURE); } int P = atoi(argv[1]); N = atoi(argv[2]); // Set up IDs for threads (need a separate variable for each since they're // shared among threads). int * threadIDs = new int[P]; for (int i = 0; i < P; ++i) threadIDs[i] = i; // Start P new threads, each with different ID. pthread_t * threads = new pthread_t[P]; for (int i = 0; i < P; ++i) pthread_create(&threads[i], NULL, threadFcn, (void *) &threadIDs[i]); // Wait for all threads to complete. for (int i = 0; i < P; ++i) pthread_join(threads[i], NULL); // Clean up and exit. delete [] threadIDs; delete [] threads; cout << "That's all, folks!\n"; return EXIT_SUCCESS; } // ---- Code to be executed by each thread ---- void * threadFcn(void * threadArg) { int myID = * (int *) threadArg; // Make strings containing messages to print to improve the odds that // they'll print atomically. (This works most of the time, but not // always. Probably the printing should be done as part of the critical // region.) ostrstream startMsgStream; startMsgStream << "thread " << myID << " starting critical region\n"; ostrstream endMsgStream; endMsgStream << "thread " << myID << " ending critical region\n"; string startMsg = startMsgStream.str(); string endMsg = endMsgStream.str(); for (int i = 0; i < N; ++i) { cout << startMsg; usleep(rand() % CR_DELAY); cout << endMsg; usleep(rand() % NON_CR_DELAY); } pthread_exit((void* ) NULL); }