1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/******************************************************** 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * An example source module to accompany... 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * "Using POSIX Threads: Programming with Pthreads" 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * by Brad nichols, Dick Buttlar, Jackie Farrell 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * O'Reilly & Associates, Inc. 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ******************************************************** 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * once_exam.c 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * An example of using the pthreads_once() call to execute an 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * initialization procedure. 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * A program spawns multiple threads and each one tries to 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * execute the routine welcome() using the once call. Only 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the first thread into the once routine will actually 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * execute welcome(). 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The program's main thread synchronizes its exit with the 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * exit of the threads using the pthread_join() operation. 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <sys/types.h> 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h> 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define NUM_THREADS 10 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic pthread_once_t welcome_once_block = PTHREAD_ONCE_INIT; 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid welcome(void) 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("welcome: Welcome\n"); 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid *identify_yourself(void *arg) 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int rtn; 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((rtn = pthread_once(&welcome_once_block, 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown welcome)) != 0) { 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fprintf(stderr, "pthread_once failed with %d",rtn); 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_exit((void *)NULL); 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("identify_yourself: Hi, I'm a thread\n"); 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return(NULL); 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern int 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmain(void) 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int *id_arg, thread_num, rtn; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t threads[NUM_THREADS]; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown id_arg = (int *)malloc(NUM_THREADS*sizeof(int)); 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (thread_num = 0; thread_num < NUM_THREADS; (thread_num)++) { 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown id_arg[thread_num] = thread_num; 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (( rtn = pthread_create(&threads[thread_num], 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NULL, 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown identify_yourself, 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void *) &(id_arg[thread_num]))) 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown != 0) { 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fprintf(stderr, "pthread_create failed with %d",rtn); 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown exit(1); 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (thread_num = 0; thread_num < NUM_THREADS; thread_num++) { 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_join(threads[thread_num], NULL); 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //printf("main: joined to thread %d\n", thread_num); 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("main: Goodbye\n"); 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 82