/* Program to compute sum of the first N positive integers */ /* using several concurrent worker threads. */ /* This version uses four threads of control: */ /* - main thread does setup and final output */ /* - worker thread 0 computes the sum for even integers */ /* - worker thread 1 computes the sum for odd integers */ /* - checker thread uses the formula to check */ /* Based on example from page 161 of the CPSC 457 textboook. CLW */ /* Usage: cc -pthread -o summer summer.c */ /* ./summer 10 */ #include #include int sum; /* global variable shared by all threads */ int oddsum; /* global variable shared by all threads */ int evensum; /* global variable shared by all threads */ int limit; /* global variable shared by all threads */ int checksum; /* global variable shared by all threads */ pthread_t eventid, oddtid, checkertid; /* thread identifiers */ void *evensummer(void *param); /* the worker thread for even nums */ void *oddsummer(void *param); /* the worker thread for odd nums */ void *checker(void *param); /* the main checker thread */ int main(int argc, char *argv[]) { pthread_attr_t attr; /* set of thread attributes */ int i; /* check command line argument */ if( argc != 2 ) { fprintf(stderr, "Usage: ./summer N\n"); return -1; } limit = atoi(argv[1]); if( limit < 0 ) { fprintf(stderr, "Value must be non-negative!\n"); return -1; } sum = 0; /* get the default attributes */ pthread_attr_init(&attr); /* create the two worker threads */ pthread_create(&eventid, &attr, evensummer, argv[1]); pthread_create(&oddtid, &attr, oddsummer, argv[1]); /* create the checker thread */ pthread_create(&checkertid, &attr, checker, argv[1]); /* wait for the worker threads to exit */ pthread_join(eventid, NULL); pthread_join(oddtid, NULL); /* wait for the checker thread to exit */ pthread_join(checkertid, NULL); /* output the final result */ sum += evensum; sum += oddsum; printf("Main says that the sum of the first %d positive integers is: %d\n", limit, sum); } /* The even worker thread will begin control in this function. */ /* This one adds up all the even integers. */ void *evensummer(void *param) { int i; fprintf(stderr, "The even number worker thread is underway\n"); /* main loop */ evensum = 0; for( i = 0; i <= limit; i += 2 ) { evensum += i; } fprintf(stderr, "The even number worker thread is done: %d\n", evensum); pthread_exit(0); } /* The odd worker thread will begin control in this function. */ /* This one adds up all the odd integers. */ void *oddsummer(void *param) { int i; fprintf(stderr, "The odd number worker thread is underway\n"); /* main loop */ oddsum = 0; for( i = 1; i <= limit; i += 2 ) { oddsum += i; } fprintf(stderr, "The odd number worker thread is done: %d\n", oddsum); pthread_exit(0); } /* The other thread will begin control in this function. */ /* It uses the known formula to check the sum answer. */ void *checker(void *param) { int answer; int n; /* initialize */ n = atoi(param); answer = n * (n + 1) / 2; /* output the formula result */ printf("Checker says that the sum of the first %d positive integers should be: %d\n", n, answer); pthread_exit(0); }