Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 [ 162 ] 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

5 pthread mutex t mutex:

6 long counter:

7 } shared = {

8 PTHREAD MUTEX INITIALIZER

9 }:

10 void *incr(void *):

11 int

12 mainCint argc. char **argv)

13 {

14 int i. nthreads:

15 pthread t tid[MAXNTHREADS]:

16 if (argc != 3)

17 err quit( usage: incr pxmutexl <#loops> <#threads> ):

18 nloop = atoi(argv[l]):

19 nthreads - min(atoi(argv[2]). MAXNTHREADS):

20 /* блокировка взаимного исключения */

21 Pthread mutexJock(&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 PthreadJoin(tid[i]. NULL):

33 }

34 printf( microseconds: X.Of usec\n . Stop time()):

35 if (shared.counter != nloop * nthreads)

36 printf( error: counter = Xld\n . shared.counter);

37 exit(O):

38 }

Общие данные

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

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

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



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

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

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

/ /bench / i ncr pxmutexl. с

39 void *

40 incrCvoid *arg)

41 {

42 int i;

43 for (i - 0; i < nloop; i++) {

44 Pthread mutexJockC&shared.mutex):

45 shared.counter++:

46 Pthread mutex unlock(&shared.mutex);

47 }

48 return(NULL);

49 }

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

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

Блокировки чтения-записи

Программа, использующая блокировки чтения-записи, является слегка измененной версией программы с взаимными исключениями Posix. Поток должен установить блокировку файла, прежде чем увеличивать общий счетчик.

ПРИМЕЧАНИЕ -

Существует не так уж много систем, в которых реализованы блокировки чтения-записи, являющиеся частью стандарта Unix 98 и разрабатываемые рабочей группой Posix.Ij. Измерения в этом разделе проводились в системе Solaris 2.6 с использованием блокировок, описанных в документации на странице rwlock(3T). Эта реализация обеспечивает тот же набор функций, что и предлагаемые блокировки чтения-записи Posix. Для использования этих функций мы применяем тривиальные функции-обертки.

В Digital Unix 4.0В мы использовали блокировки чтения-записи поточно-независимых служб, описанные на странице документации tis rwlock. Мы не приводим листингов с несущественными изменениями, необходимыми для использования этих блокировок.

В листинге А.21 приведен текст функции mai п, а в листинге А.22 - текст функции incr.

Листинг А.21. Функция main для блокировок чтения-записи

bench/i ncr rwlоск1.с

1 #include unpipc.h

2 #include <synch.h> /* Заголовочный файл для Solaris */



3 void Rw wrlock(rwlock t *rwptr):

4 void Rw unlock(rwlock t *rwptr):

5 #define MAXNTHREADS 100

6 int nloop:

7 struct {

8 rwlock t rwlock; /* тип данных Solaris */

9 long counter:

10 } shared; /* инициализация 0 -> USYNCJHREAD */

11 void *incr(void *);

12 int

13 mainCint argc. char **argv)

14 {

15 int i. nthreads:

16 pthread t tid[MAXNTHREADS]:

17 if (argc != 3)

18 err quit( usage: incr rwlockl <#loops> <#threads> );

19 nloop = atoi(argv[l]):

20 nthreads - min(atoi(argv[2]). MAXNTHREADS);

21 /* получение блокировки на запись */

22 Rw wrlock(&shared.rwlock);

23 /* создание всех потоков */

24 Set concurrency(nthreads):

25 for (i = 0: i < nthreads; i++) {

26 Pthread create(&tid[i], NULL, incr, NULL);

27 }

28 /* запуск таймера и снятие блокировки */

29 Start time():

30 Rw unlock(&shared.rwlock);

31 /* ожидание завершения всех потоков */

32 for (i = 0: i < nthreads; i++) {

33 PthreadJoin(tid[i]. NULL);

34 }

35 printf( microseconds; .Of usec\n . Stop time()):

36 if (shared.counter 1= nloop * nthreads)

37 printf( error: counter = ld\n . shared.counter):

38 exit(O):

39 }

Листинг A.22. Увеличение общего счетчика с использованием блокировок чтения-записи

bench/i ПС r rwlоск1.с

40 void *

41 incr(void *arg)

42 {

43 int i:

44 for (i = 0: i < nloop; i++) { продолжение



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 [ 162 ] 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.