1 /* Multi-thread searching.
2 Illustrates: thread cancellation, cleanup handlers. */
10 /* Defines the number of searching threads */
13 /* Function prototypes */
15 void print_it(void *);
17 /* Global variables */
18 pthread_t threads[NUM_THREADS];
29 /* create a number to search for */
31 printf("Searching for the number = %d...\n", pid);
33 /* Initialize the mutex lock */
34 pthread_mutex_init(&lock, NULL);
36 /* Create the searching threads */
37 for (i=0; i<NUM_THREADS; i++)
38 pthread_create(&threads[i], NULL, search, (void *)pid);
40 /* Wait for (join) all the searching threads */
41 for (i=0; i<NUM_THREADS; i++)
42 pthread_join(threads[i], NULL);
44 printf("It took %d tries to find the number.\n", tries);
46 /* Exit the program */
50 /* This is the cleanup function that is called
51 when the threads are cancelled */
53 void print_it(void *arg)
55 int *try = (int *) arg;
58 /* Get the calling thread's ID */
61 /* Print where the thread was in its search when it was cancelled */
62 printf("Thread %lx was canceled on its %d try.\n", tid, *try);
65 /* This is the search routine that is executed in each thread */
67 void *search(void *arg)
73 /* get the calling thread ID */
76 /* use the thread ID to set the seed for the random number generator */
77 /* Since srand and rand are not thread-safe, serialize with lock */
78 pthread_mutex_lock(&lock);
80 i = rand() & 0xFFFFFF;
81 pthread_mutex_unlock(&lock);
84 /* Set the cancellation parameters --
85 - Enable thread cancellation
86 - Defer the action of the cancellation */
88 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
89 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
91 /* Push the cleanup routine (print_it) onto the thread
92 cleanup stack. This routine will be called when the
93 thread is cancelled. Also note that the pthread_cleanup_push
94 call must have a matching pthread_cleanup_pop call. The
95 push and pop calls MUST be at the same lexical level
98 /* Pass address of `ntries' since the current value of `ntries' is not
99 the one we want to use in the cleanup function */
101 pthread_cleanup_push(print_it, (void *)&ntries);
105 i = (i + 1) & 0xFFFFFF;
108 /* Does the random number match the target number? */
110 /* Try to lock the mutex lock --
111 if locked, check to see if the thread has been cancelled
112 if not locked then continue */
113 while (pthread_mutex_trylock(&lock) == EBUSY)
114 pthread_testcancel();
116 /* Set the global variable for the number of tries */
118 printf("Thread %lx found the number!\n", tid);
120 /* Cancel all the other threads */
121 for (j=0; j<NUM_THREADS; j++)
122 if (threads[j] != tid) pthread_cancel(threads[j]);
124 /* Break out of the while loop */
128 /* Every 100 tries check to see if the thread has been cancelled. */
129 if (ntries % 100 == 0) {
130 pthread_testcancel();
134 /* The only way we can get here is when the thread breaks out
135 of the while loop. In this case the thread that makes it here
136 has found the number we are looking for and does not need to run
137 the thread cleanup function. This is why the pthread_cleanup_pop
138 function is called with a 0 argument; this will pop the cleanup
139 function off the stack without executing it */
141 pthread_cleanup_pop(0);