Книга: UNIX: взаимодействие процессов

Взаимные исключения Posix

Взаимные исключения Posix

В листинге А.19 приведены глобальные переменные и функция main пpoгрaммы, измеряющей быстродействие взаимных исключений Posix.

Листинг А.19. Глобальные переменные и функция main для взаимных исключений Posix

//bench/incr_pxmutex1.с
1  #include "unpipc.h"
2  #define MAXNTHREADS 100
3  int nloop;
4  struct {
5   pthread_mutex_t mutex;
6   long counter;
7  } shared = {
8   PTHREAD_MUTEX_INITIALIZER
9  };
10 void *incr(void *);
11 int
12 main(int argc, char **argv)
13 {
14  int i, nthreads;
15  pthread_t tid[MAXNTHREADS];
16  if (argc != 3)
17   err_quit("usage: incr_pxmutex1 <#loops> <#threads>");
18  nloop = atoi(argv[1]);
19  nthreads = min(atoi(argv[2]), MAXNTHREADS);
20  /* блокировка взаимного исключения */
21  Pthread_mutex_lock(&shared.mutex);
22  /* создание потоков */
23  Set_concurrency(nthreads);
24  for (i = 0; i < nthreads; i++) {
25   Pthread_create(&tid[i], NULL, incr, NULL);
26  }
27  /* запуск таймера и разблокирование взаимного исключения */
28  Start_time();
29  Pthread_mutex_unlock(&shared.mutex);
30  /* ожидание завершения работы потоков */
31  for (i = 0; i < nthreads; i++) {
32   Pthread_join(tid[i], NULL);
33  }
34  printf("microseconds: %.0f usecn", Stop_time());
35  if (shared.counter != nloop * nthreads)
36   printf("error: counter = %ldn", shared, counter);
37  exit(0);
38 }

Общие данные

4-9 Совместно используемые потоками данные состоят из взаимного исключения и счетчика. Взаимное исключение инициализируется статически.

Блокирование взаимного исключения и создание потоков

20-26 Основной поток блокирует взаимное исключение перед созданием прочих потоков, чтобы ни один из них не получил это исключение до тех пор, пока все они не будут созданы. Вызывается функция set_concurrency, создаются потоки. Каждый поток выполняет функцию incr, текст которой будет приведен позже. 

Запуск таймера и разблокирование взаимного исключения

27-36 После создания всех потоков главный поток запускает таймер и освобождает взаимное исключение. Затем он ожидает завершения всех потоков, после чего останавливает таймер и выводит полное время работы. В листинге А.20 приведен текст функции incr, выполняемой каждым из потоков.

Листинг А.20. Функция incr, выполняемая потоками

//bench/incr_pxmutex1.c
39 void *
40 incr(void *arg)
41 {
42  int i;
43  for (i = 0; i < nloop; i++) {
44   Pthread_mutex_lock(&shared.mutex);
45   shared.counter++;
46   Pthread_mutex_unlock(&shared.mutex);
47  }
48  return(NULL);
49 }

Увеличение счетчика — критическая область кода

44-46 Операция увеличения счетчика осуществляется после получения блокировки на взаимное исключение. После этого взаимное исключение разблокируется.

Оглавление книги


Генерация: 1.546. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз