#include #include #include /**** * * This program is a simple illustration of threads. It is a version of the * f-test program from lab 6, here using a thread instead of the "heavy-weight" * process created by calling fork. * * The program takes an integer command-line argument, N. The program creates * a thread to print consecutive odd numbers from 1 to N. The main thread * prints consecutive even integers from 2 to N. * * The main thread and created thread run asynchronously, in the same way that * the main process and forked process ran asynchronously in the lab 6 * program. This means that there is the same form of race condition between * the threads, such that standard output of odd and even numbers is * unpredictably interspersed. * */ /** * Print consecutive odd integers from 1 to arg. The signature of this * function is that required for a thread start routine. */ void* print_odds(void* arg) { int i; int n = *((int*) arg); for (i = 1; i <= n; i += 2) { printf("%d\n", i); } return NULL; } /* * Print consecutive odd and even integers, up to n. A created thread prints * the odds, the main thread prints the evens. */ void print_numbers(int n) { int i; /* loop index */ pthread_t tid; /* id for thread to be created */ int *arg; /* argument sent to thread start routine */ /* * Allocate storage for the start routine argument, which must be void*. */ if ((arg = malloc(sizeof(int))) == NULL) { perror("malloc"); exit(-1); } /* * Initialize the argument. */ *arg = n; /* * Create the thread, which means its start routine begins quasi-concurrent * execution. */ if (pthread_create(&tid, NULL, print_odds, arg)) { perror("pthread_create"); exit(-1); } /* * Back in the main thread, print out even integers, concurrently with the * odd printing in the thread. */ for (i = 2; i <= n; i += 2) { printf("\t%d\n", i); } /* * Wait for the thread to terminate. */ if (pthread_join(tid, NULL)) { perror("pthread_join"); exit(-1); } } /* * Get the single command-line argument and call print_numbers with it. */ int main(int argc, char *argv[]) { int n; /* integer value of command-line arg */ char* end; /* for use with strtol */ /* * Make sure there is exactly one command-line arg. */ if (argc != 2) { fprintf(stderr, "usage: %s \n", argv[0]); exit(1); } /* * Convert and validate arg as an integer. */ n = strtol(argv[1], &end, 10); if (*end != '\0') { fprintf(stderr, "%s - %s is not a valid integer\n", argv[0], argv[1]); exit(1); } /* * Do the deed. */ print_numbers(n); return EXIT_SUCCESS; }