// // Simple program demonstrating the use of threads to // sum the integers 1 through N. // // Command-line arguments are N and P (number of threads). // #include #include // has setprecision() #include // has exit(), etc. #include // has pthread_ routines #include "threads-timer.h" // has timer() // ---- Global variables --------------------------------------------- // (Global variables are a bit ugly, but this is an easy way to create // a variable all threads can access.) int N; // number of numbers to sum int P; // number of threads double sum; // sum (double to avoid overflow) pthread_mutex_t sumLock; // lock for shared variable "sum" // ---- Code to be executed by each thread --------------------------- // Computes partial sum of N/P of the elements (starting with // myID+1 and summing every P-th element) and adds it to sum. void * addSome(void * threadArg) { int * myID = (int *) threadArg; // Calculate partial sum. double partialSum = 0; for (int i = (*myID)+1; i <= N; i+=P) { partialSum += i; } // Add to global sum (using lock to be sure only one thread // at a time performs this operation). pthread_mutex_lock(&sumLock); sum += partialSum; pthread_mutex_unlock(&sumLock); return NULL; } // ---- Main program ------------------------------------------------- int main(int argc, char* argv[]) { // Process command-line arguments. if (argc < 3) { cerr << "Usage: " << argv[0] << " highestNum numThreads\n"; exit(EXIT_FAILURE); } N = atoi(argv[1]); // N, P are global variables. P = atoi(argv[2]); cout << "Summing the first " << N << " positive integers using " << P << " threads:\n"; // Set up to time things. double startTime = timer(); // Initialize sum, lock. pthread_mutex_init(&sumLock, NULL); sum = 0; // no need to lock here since we have // only one thread at this point. // Set up IDs for threads. int * threadIDs = new int[P]; for (int i = 0; i < P; ++i) threadIDs[i] = i; // Start P new threads. pthread_t * threads = new pthread_t[P]; for (int i = 0; i < P; ++i) { if (pthread_create(&threads[i], NULL, addSome, (void *) &threadIDs[i]) != 0) cerr << "Unable to create thread " << i << endl; } // Wait for all threads to complete. for (int i = 0; i < P; ++i) { if (pthread_join(threads[i], NULL) != 0) cerr << "Unable to perform join on thread " << i << endl; } // Clean up. pthread_mutex_destroy(&sumLock); // Print results. cout << "Sum = " << setprecision(40) << sum << endl; double endTime = timer(); cout << "Elapsed time (seconds) = " << setprecision(4) << endTime - startTime << endl; return EXIT_SUCCESS; }