24 pthread_testcancel ();
25 }
26
27 /*
28 * Cancellation cleanup handler for the contractor thread. It
29 * will cancel and detach each worker in the team.
30 */
31 void cleanup (void *arg)
32 {
33 team_t *team = (team_t *)arg;
34 int count, status;
35
36 for (count = team->join_i; count < THREADS; count++) {
37 status = pthread_cancel (team->workers[count]);
38 if (status != 0)
39 err_abort (status, 'Cancel worker');
40
41 status = pthread_detach(team->workers[count]);
42 if (status != 0)
43 err_abort (status, 'Detach worker');
44 printf ('Cleanup: canceled %d
', count);
45 }
46 }
47
48 /*
49 * Thread start routine for the contractor. It creates a team of
50 * worker threads, and then joins with them. When canceled, the
51 * cleanup handler will cancel and detach the remaining threads.
52 */
53 void *thread_routine (void *arg)
54 {
53 team_t team; /* team info */
56 int count;
57 void *result; /* Return status */
58 int status;
59
60 for (count = 0; count < THREADS; count++) {
61 status = pthread_create (
62 &team.workers[count], NULL, worker_routine, NULL);
63 if (status != 0)
64 err_abort (status, 'Create worker');
55 }
66 pthread_cleanup_push (cleanup, (void*)&team);
67
68 for (team.join_i = 0; team.join_i < THREADS; team.join_i++) {
69 status = pthread_join (team.workers[team.join_i], &result);
70 if (status != 0)
71 err_abort (status, 'Join worker');
72 }
73
74 pthread_cleanup_pop (0);
75 return NULL;
76 }
77
78 int main (int argc, char *argv[])
79 {
80 pthread_t thread_id;
81 int status;
82
83 #ifdef sun
84 /*
85 * On Solaris 2.5, threads are not timesliced. To ensure
86 * that our threads can run concurrently, we need to
87 * increase the concurrency level to at least 2 plus THREADS
88 * (the number of workers).
89 */
90 DPRINTF (('Setting concurrency level to %d
', THREADS+2));
91 thr_setconcurrency (THREADS+2);
92 #endif
93 status = pthread_create (&thread_id, NULL, thread_routine, NULL);
94 if (status != 0)
95 err_abort (status, 'Create team');
96 sleep (5);
97 printf ('Cancelling...
');
98 status = pthread_cancel (thread_id);
99 if (status != 0)
100 err_abort (status, 'Cancel team');
101 status = pthread_join (thread_id, NULL);
102 if (status != 0)
103 err_abort (status, 'Join team');
104 }
5.4 Thread-specific data
No,
When a function in a single threaded program needs to create private data that persists across calls to that function, the data can be allocated statically in memory. The name's scope can be limited to the function or file that uses it (static) or it can be made global (extern).
It is not quite that simple when you use threads. All threads within a process share the same address space,