Listing 1. C Source Code for hello_world #include #include #include #include #define THREAD_COUNT 32 /* String output data */ static const char *string = "Hello World!\n"; static int cursor = 0; pthread_mutex_t print_lock = PTHREAD_MUTEX_INITIALIZER; /* Runtime statistics */ static int chars_printed = 0; pthread_mutex_t statistics_lock = PTHREAD_MUTEX_INITIALIZER; /* Print one character of the string "Hello World!" to stdout */ /* Returns a pointer to the character printed */ static char *say_hello(void) { char *printed_letter = NULL; printf("%c", string[cursor]); if (++cursor > strlen(string)) { cursor = 0; fflush(stdout); } printed_letter = (char *) malloc(1); if (printed_letter) { *printed_letter = string[cursor]; } return printed_letter; } /* A "bug-free" printer function */ static void *good_printer(void *data) { char *c = NULL; while(1) { c = NULL; pthread_mutex_lock(&print_lock); pthread_mutex_lock(&statistics_lock); c = say_hello(); if (c) free(c); chars_printed++; pthread_mutex_unlock(&statistics_lock); pthread_mutex_unlock(&print_lock); } return NULL; } /* A buggy printer function */ static void *bad_printer(void *data) { while(1) { ed_mutex_lock(&statistics_lock); pthread_mutex_lock(&print_lock); say_hello(); chars_printed++; pthread_mutex_unlock(&print_lock); pthread_mutex_unlock(&statistics_lock); } return NULL; } int main (int argc, char **argv) { pthread_t threads[THREAD_COUNT]; int i; /* Spawn many good children threads */ for (i = 1; i < THREAD_COUNT; i++) { if (0 != pthread_create(&threads[i], NULL, good_printer, NULL)) { perror("pthread_create"); exit(EXIT_FAILURE); } } /* Spawn one bad child thread */ if (0 != pthread_create(&threads[0], NULL, bad_printer, NULL)) { perror("pthread_create"); exit(EXIT_FAILURE); } pthread_join(threads[0], NULL); return EXIT_SUCCESS; }