7 * Loop until canceled. The thread can be canceled only
8 * when it calls pthread_testcancel, which it does each 1000
9 * iterations. 10 */
11 void *thread_routine (void *arg)
12 {
13 DPRINTF (("thread_routine starting\n"));
14 for (counter = 0; ; counter++)
15 if ((counter % 1000) == 0) {
16 DPRINTF (("calling testcancel\n"));
17 pthread_testcancel ();
18 }
19 }
20
21 int main (int argc, char *argv[])
22 {
23 pthread_t thread_id;
24 void *result;
25 int status;
26
27 #ifdef sun
28 /*
29 * On Solaris 2.5, threads are not timesliced. To ensure
30 * that our two threads can run concurrently, we need to
31 * increase the concurrency level to 2.
32 */
33 DPRINTF (("Setting concurrency level to 2\n"));
34 thr_setconcurrency (2);
35 #endif
36 status = pthread_create (
37 &thread_id, NULL, thread_routine, NULL);
38 if (status != 0)
39 err_abort (status, "Create thread");
40 sleep (2);
41
42 DPRINTF (("calling cancel\n"));
43 status = pthread_cancel (thread_id);
44 if (status != 0)
45 err_abort (status, "Cancel thread");
46
47 DPRINTF (("calling join\n"));
48 status = pthread_join (thread_id, &result);
49 if (status != 0)
50 err_abort (status, "Join thread");
51 if (result == PTHREAD_CANCELED)
52 printf ("Thread canceled at iteration %d\n", counter);
53 else
54 printf ("Thread was not canceled\n");
55 return 0;
56 }
A thread can disable cancellation around sections of code that need to complete without interruption, by calling pthread_setcancelstate. For example, ifa database update operation takes two separate write calls, you wouldn't want to complete the first and have the second canceled. If you request that a thread be canceled while cancellation is disabled, the thread remembers that it was canceled but won't do anything about it until after cancellation is enabled again. Because enabling cancellation isn't a
When a thread may be canceled while it holds private resources, such as a locked mutex or heap storage that won't ever be freed by any other thread, those resources need to be released when the thread is canceled. If the thread has a mutex locked, it may also need to "repair" shared data to restore program invariants.
If you don't have a thread's identifier, you can't cancel the thread. That means that, at least using portable POSIX functions, you can't write an "idle thread killer" that will arbitrarily terminate threads in the process. You can only cancel threads that you created, or threads for which the creator (or the thread itself) gave you an identifier. That generally means that cancellation is restricted to operating within a subsystem.
5.3.1 Deferred cancelability
"Deferred cancelability" means that the thread's cancelability type has been set to PTHREAD_CANCEL_DEFERRED and the thread's cancelability enable has been set to PTHREAD_CANCEL_ENABLE. The thread will only respond to cancellation requests when it reaches one of a set of "cancellation points."
The following functions are always cancellation points on any Pthreads system:
pthread_cond_wait fsync
pthread_cond_timedwait mq_receive pthread_join mq_send
pthread_testcancel msync
sigwait nanosleep
aio_suspend open
close pause
creat read
fcntl (F_SETLCKW) sem_wait