Читаем Programming with POSIX® Threads полностью

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 cancellation point, you also need to test for a pending cancel request if you want a cancel processed immediately.

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. Cleanup handlers provide the mechanism to accomplish the cleanup, somewhat like process atexit handlers. After acquiring a resource, and before any cancellation points, declare a cleanup handler by calling pthread_cleanup_ push. Before releasing the resource, but after any cancellation points, remove the cleanup handler by calling pthread_cleanup_pop.

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.

<p>5.3.1 Deferred cancelability</p>

"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

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных