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

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

Листинг 10.24 (продолжение)

6 return(unhnk(pathname)):

Функция sem post

в листинге 10.25 приведен текст функции sem post, которая увеличивает значение семафора.

11-12 Мы записываем один байт в FIFO. Если канал был пуст, это приведет к возобновлению выполнения всех процессов, заблокированных в вызове read для этого канала.

Листинг 10.25. Функция sem post

my pxsem fi fо/sem post.с

1 finclude unpipc.h

2 finclude semaphore.h

3 Int

4 iT\ysem post(mysem t *sem)

6 char c:

7 if (sem->sem mag1c !- SEM MAGIC) {

8 errno = EINVAL;

9 return(-l);

10 }

11 If (write(sem->sem fd[l]. &c, 1) == 1)

12 return(0);

13 return(-l);

14 }

Функция sem wait

Последняя функция для работы с именованными семафорами Posix - sem wait. Ее текст приведен в листинге 10.26.

Листинг 10.26. Функция sem wait

my pxsem f1fo/sem wa1t.с

1 finclude unpipc.h

2 finclude semaphore.h

3 int

4 mysem walt(mysem t *sem)

6 char c;

7 If (sem->sem mag1c != SEM MAGIC) {

8 errno = EINVAL:

9 return(-l);

10 }

11 If (read(sem->sem fd[0], &c. 1) == 1)

12 return(O):

13 return(-l):

14 }



11-12 Мы считываем 1 байт из канала FIFO, причем работа приостанавливается, если канал пуст.

Мы еще не реализовали функцию sem trywait, но это можно сделать, установив флаг отключения блокировки для канала и используя обычный вызов read. Мы также не реализовали фзшкцию sem getval ue. В некоторых реализациях при вызове функции stat или fstat возвращается количество байтов в именованном или неименованном канале, причем оно помещается в поле st si ze структуры stat. Однако это не гарантируется стандартом Posix и, следовательно, не обязательно будет работать в других системах. Пример реализации этих двух функций для работы с семафорами Posix приведен в следующем разделе.

10.15. Реализация с помощью отображения в память

Теперь займемся реализацией именованных семафоров Posix с помощью отображаемых в память файлов вместе со взаимными исключениями и условными переменными Posix. Реализация, аналогичная данной, приведена в разделе В. 11.3 Обоснования стандарта IEEE 1996 [8].

ПРИМЕЧАНИЕ -

Отображаемые в память файлы описаны в главах 12 и 13. Данный раздел можно отложить, с тем чтобы вернуться к нему после прочтения этих глав.

Прежде всего приведем текст нащего заголовочного файла semaphore.h (листинг 10.27), в котором определяется фундаментальный тип sem t.

Тип sem t

1-7 Структура данных семафора содержит взаимное исключение, условную переменную и беззнаковое целое, в котором хранится текущее значение семафора. Как уже говорилось в связи с листингом 10.21, поле sem magi с получает значение SEM MAGIC при инициализации структуры.

Листинг 10.27. Заголовочный файл semaphore.h

/ /my pxsem niiiap/ semaphore. h

1 /* фундаментальный тип */

2 typedef struct {

3 pthread mutex t sem mutex: /* блокируется при проверке и изменении

значения семафора */

4 pthread cond t sem cond: /* при изменении нулевого значения */

5 unsigned int sem count; /* значение семафора */

6 int sem magic: /* магическое значение, если семафор открыт */

7 } mysem t:

8 Idefine SEM MAGIC 0x67458923

9 #ifdef SEMJAILED

10 #undef SEMJAILED

11 #define SEMJAILED ((riysemj *)(-l)) /* чтобы избежать предупреждений

компилятора */

12 #endif



Функция sem open

в листинге 10.28 приведен текст первой части функции sem open, которая может использоваться для создания нового семафора или открытия существующего.

Листинг 10.28. Функция sem open: первая половина

my pxsem niiiap/sem open .с

1 finclude unpipc.h

2 finclude semaphore.h

3 finclude <stdarg.h> /* для списков аргументов переменной длины */

4 fdefine MAX TRIES 10 /* количество попыток инициализации */

5 mysem t *

6 mysem open(const char *pathname. int oflag; ... )

8 int fd. 1. created. save errno:

9 mode t mode:

10 vajist ap:

11 mysem t *sem. semi nit:

12 struct stat statbuff:

13 unsigned int value:

14 pthread mutexattr t mattr:

15 pthread condattr t cattr:

16 created - 0:

17 sem - MAPJAILED; /* [sic] */

18 again;

19 if (oflag & OJREAT) {

20 va start(ap. oflag): /* ap инициализируется последним явно

указанным аргументом */

21 mode = va arg(ap. vajrodej) & -SJXUSR:

22 value va arg(ap. unsigned int):

23 va end(ap):

24 /* открываем с указанием флага OJXCL и установкой бита

user-execute */

25 fd - open (pathname, oflag 0 EXCL OJDWR. mode SJXUSR):

26 if (fd < 0) {

27 if (errno == EEXIST && (oflag & OJXCL) == 0)

28 goto exists: /* уже существует. OK */

29 else

30 return(SEMJAILED):

31 }

32 created - 1:

33 /* кто создает файл, тот его и инициализирует */

34 /* установка размера файла */

35 bzero(&sem1nit. sizeof(sem1n1t)):

36 if (wr1te(fd, &seminit. sizeof(semlnlt)) != sizeof(semlnlt))

37 goto err:

38 /* отображение файла в память */

39 sem = mmap(NULL. sizeof(mysemJ). PROTJEAD PROTJRITE.

40 MAPJHARED, fd. 0):

41 if (sem =- MAPJAILED)

42 goto err:



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.
Копирование материалов разрешено исключительно при условии цититирования.