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

*A semaphore, as described later in Section 6.6.6, would provide cleaner, and somewhat safer, synchronization. The thd_suspend would call sem_wait on a semaphore with an inltial value of 0, and the signal-catching function would call sem_post to wake it.

7

8 unsigned long thread_count = THREAD_COUNT;

9 unsigned long iterations = ITERATIONS;

10 pthread_mutex_t the_mutex = PTHREAD_MUTEX_INITIALIZER;

11 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

12 volatile int sentinel = 0;

13 pthread_once_t once = PTHREAD_ONCE_INIT;

14 pthread_t *array = NULL, null_pthread = {0};

15 int bottom = 0;

16 int inited = 0; 17

18 /*

19 * Handle SIGUSR1 in the target thread, to suspend it until

20 * receiving SIGUSR2 (resume).

21 */

22 void

23 suspend_signal_handler (int sig)

24 {

25  sigset_t signal_set;

26

27 /*

28 * Block all signals except SIGUSR2 while suspended.

29 */

30  sigfillset (&signal_set);

31  sigdelset (&signal_set, SIGUSR2);

32  sentinel = 1;

33  sigsuspend (&signal_set);

34

35 /*

36 * Once I'm here, I've been resumed, and the resume signal

37 * handler has been run to completion.

38 */

39  return;

40 }

41

42 /*

43 * Handle SIGUSR2 in the target thread, to resume it. Note that

44 * the signal handler does nothing. It exists only because we need

45 * to cause sigsuspend() to return.

46 */

47 void

48 resume_signal_handler (int sig)

49 {

50  return;

51 }

The suspend_init_routine function dynamically initializes the suspend/ resume package when the first call to thd_suspend is made. It is actually called indirectly by pthread_once.

15-16 It allocates an initial array of thread identifiers, which is used to record the identifiers of all threads that have been suspended. This array is used to ensure that multiple calls to thd_suspend have no additional effect on the target thread, and that calling thd_continue for a thread that is not suspended has no effect.

21-35 It sets up signal actions for the SIGUSR1 and SIGUSR2 signals, which will be used, respectively, to suspend and resume threads.

susp.c part 2 initialization

1 /*

2 * Dynamically initialize the "suspend package" when first used

3 * (called by pthread_once).

4 */

5 void

6 suspend_init_routine (void)

7 {

8  int status;

9  struct sigaction sigusrl, sigusr2;

10

11 /*

12 * Allocate the suspended threads array. This array is used

13 * to guarentee idempotency

14 */

15  bottom = 10;

16  array = (pthread_t*) calloc (bottom, sizeof (pthread_t)); 17

18 /*

19 * Install the signal handlers for suspend/resume.

20 */

21  sigusrl.sa_flags = 0;

22  sigusrl.sa_handler = suspend_signal_handler; 23

24  sigemptyset (&sigusrl.sa_mask);

25  sigusr2.sa_flags = 0;

26  sigusr2.sa_handler = resume_signal_handler;

27  sigusr2.sa_mask = sigusrl.sa_mask;

28

29  status = sigaction (SIGUSR1, &sigusrl, NULL);

30  if (status == -1)

31  errno_abort ("Installing suspend handler"); 32

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

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

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

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

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

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