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