Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

ПРИМЕЧАНИЕ

Мы снова встретимся с проблемой отмены выполнения потоков в связи с листингом 15.26, где может произойти отмена выполнения сервера с дверьми при завершении работы клиента в процессе обработки вызванной им процедуры. 

Пример

Легче всего продемонстрировать проблему нашей реализации из предыдущего раздела с помощью примера. На рис. 8.1 изображена временная диаграмма выполнения нашей программы, а текст самой программы приведен в листинге 8.9. 

Рис. 8.1. Временная диаграмма выполнения программы из листинга 8.9

Создание двух потоков

10-13 Создаются два потока, первый из которых выполняет функцию thread1, а второй — thread2. После создания первого делается пауза длительностью в одну секунду, чтобы он успел заблокировать ресурс на чтение. 

Ожидание завершения потоков

14-23 Мы ожидаем завершения работы второго потока и проверяем, что его статус имеет значение PTHREAD_CANCEL. Затем мы ждем завершения работы первого потока и проверяем, что его статус представляет собой нулевой указатель. Затем мы выводим значение трех счетчиков в структуре pthread_rwlock_t и уничтожаем блокировку.

Листинг 8.9. Тестовая программа, иллюстрирующая отмену выполнения потока

//my_rwlock_cancel/testcancel.с

1 #include "unpipc.h"

2 #include "pthread_rwlock.h"

3 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

4 pthread_t tid1, tid2;

5 void *thread1(void *), *thread2(void *);

6 int

7 main(int argc, char **argv)

8 {

9 void *status;

10 Set_concurrency(2);

11 Pthread_create(&tid1, NULL, thread1, NULL);

12 sleep(1); /* даем первому потоку возможность получить блокировку */

13 Pthread_create(&tid2, NULL, thread2, NULL);

14 Pthread_join(tid2, &status);

15 if (status != PTHREAD_CANCELED)

16 printf("thread2 status = %p\n", status);

17 Pthread_join(tid1, &status);

18 if (status != NULL)

19 printf("thread1 status = %p\n", status);

20 printf("rw_refcount = %d, rw_nwaitreaders = %d, rw_nwaitwriters = %d\n",

21 rwlock.rw_refcount, rwlock.rw_nwaitreaders,

22 rwlock.rw_nwaitwriters);

23 Pthread_rwlock_destroy(&rwlock);

24 exit(0);

25 }

26 void *

27 thread1(void *arg)

28 {

29 Pthread_rwlock_rdlock(&rwlock);

30 printf("thread1 got a read lock\n");

31 sleep(3); /* даем второму потоку возможность заблокироваться при вызове pthread_rwlock_wrlock */

32 pthread_cancel(tid2);

33 sleep(3);

34 Pthread_rwlock_unlock(&rwlock);

35 return(NULL);

36 }

37 void *

38 thread2(void *arg)

39 {

40 printf("thread2 trying to obtain a write lock\n"):

41 Pthread_rwlock_wrlock(&rwlock);

42 printf("thread2 got a write lock\n"); /* не будет выполнено */

43 sleep(1);

44 Pthread_rwlock_unlock(&rwlock);

45 return(NULL);

46 }

Функция thread1

26-36 Поток получает блокировку на чтение и ждет 3 секунды. Эта пауза дает возможность другому потоку вызвать pthread_rwlock_wrlock и заблокироваться при вызове pthread_cond_wait, поскольку блокировка на запись не может быть установлена из-за наличия блокировки на чтение. Затем первый поток вызывает pthread_cancel для отмены выполнения второго потока, ждет 3 секунды, освобождает блокировку на чтение и завершает работу.

Функция thread2
  • Читать дальше
  • 1
  • ...
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: