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

Взаимные исключения Posix между процессами

Взаимные исключения Posix между процессами

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

Листинг А.32. Функция main для измерения быстродействия взаимных исключений между процессами

//bench/incr_pmutex5.с
1  #include "unpipc.h"
2  #define MAXNPROC 100
3  int nloop;
4  struct shared {
5   pthread_mutex_t mutex;
6   long counter;
7  } *shared; /* указатель, сама структура в общей памяти */
8  void *incr(void *);
9  int
10 main(int argc, char **argv)
11 {
12  int i, nprocs;
13  pid_t childpid[MAXNPROC];
14  pthread_mutexattr_t mattr;
15  if (argc != 3)
16   err_quit("usage: incr_pxmutex5 <#loops> <#processes>");
17  nloop = atoi(argv[l]);
18  nprocs = min(atoi(argv[2]), MAXNPROC);
19  /* получение разделяемой памяти для родительского и дочерних процессов */
20  shared = My_shm(sizeof(struct shared));
21  /* инициализация взаимного исключения и его блокировка */
22  Pthread_mutexattr_init(&mattr);
23  Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
24  Pthread_mutex_init(&shared->mutex, &mattr);
25  Pthread_mutexattr_destroy(&mattr);
26  Pthread_mutex_lock(&shared->mutex);
27  /* порождение дочерних процессов */
28  for (i = 0; i < nprocs; i++) {
29   if ((childpid[i] = Fork()) == 0) {
30    incr(NULL);
31    exit(0);
32   }
33  }
34  /* родительский процесс: запуск таймера и разблокирование взаимного исключения */
35  Start_time();
36  Pthread_mutex_unlock(&shared->mutex);
37  /* ожидание завершения всех дочерних процессов */
38  for (i = 0; i < nprocs; i++) {
39   Waitpid(childpid[i], NULL, 0);
40  }
41  printf("microseconds: %.0f usecn", Stop_time());
42  if (shared->counter != nloop * nprocs)
43   printf("error: counter = %ldn", shared->counter);
44  exit(0);
45 }

19-20 Поскольку мы запускаем несколько процессов, структура shared должна располагаться в разделяемой памяти. Мы вызываем функцию my_shm, текст которой приведен в листинге А.31.

21-26 Поскольку взаимное исключение помещено в разделяемую память, мы не можем статически инициализировать его, поэтому мы вызываем pthread_mutex_init после установки атрибута PTHREAD_PROCESS_SHARED. Взаимное исключение блокируется.

27-36 После создания дочерних процессов и запуска таймера блокировка снимается.

37-43 Родительский процесс ожидает завершения всех дочерних, после чего останавливает таймер.

Листинг А.33. Увеличение счетчика с использованием взаимных исключений между процессами

//bench/incr_pxmutex5.с
46 void *
47 incr(void *arg)
48 {
49  int i;
50  for (i = 0; i < nloop; i++) {
51   Pthread_mutex_lock(&shared->mutex);
52   shared->counter++;
53   Pthread_mutex_unlock(&shared->mutex);
54  }
55  return(NULL);
56 }

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


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