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

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

Функция sem getvalue

в листинге 10.35 приведен текст последней функции в этой реализации - sem getvalue. Она возвращает текущее значение семафора. 11-16 Мы блокируем соответствующее взаимное исключение и считываем значение семафора.

Листинг 10.35. Функция sem getvalue

/ / myjjxs em niiiap/ s em get va 1 ue. с

1 finclude unpipc.h

2 finclude semaphore.h

3 int

4 mysem getvalue(mysem t *sem. int *pvalue)

6 int П-.

7 if (sem->sem magic != SEM MAGIC) {

8 errno = EINVAL;

9 return(-l);

10 }

11 if ( (n = pthread mutexJock(&sem->sem mutex)) != 0) {

12 errno - n;

13 return(-l):

14 }

15 *pvalue = sem->sem count:

16 pthread mutex unlock(&sem->sem mutex):

17 return(O);

18 }

Из этой реализации видно, что семафорами пользоваться проще, чем взаимными исключениями и условными переменными.

10.16. Реализация с использованием семафоров System V

Приведем еще один пример реализации именованных семафоров Posix - на этот раз с использованием семафоров System V. Поскольку семафоры System V появились раньще, чем семафоры Posix, эта реализация позволяет использовать последние в системах, где их поддержка не предусмотрена производителем.

ПРИМЕЧАНИЕ -

Семафоры System V описаны в главе И. Этот раздел можно пропустить при первом чтении, с тем чтобы вернуться к нему по прочтении 11 главы.

Начнем, как обычно, с заголовочного файла semaphore. h (листинг 10.36), который определяет фундаментальный тип данных sem t.

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

my pxsem svsem/semaphore.h

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

2 typedef struct {

продолжение



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

3 int sem semid: /* идентификатор семафора System V */

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

5 } mysem t:

6 fdefine SEM MAGIC 0x45678923

7 fifdef SEMJAILED

8 fundef SEMJAILED

9 fdefine SEMJAILED ((mysemj *)(-!)) /* исключаем предупреждения

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

10 fendif

11 fifndef SEMVMX

12 fdefine SEMVMX 32767 /* исторически сложившееся максимальное значение

для семафора System V */

13 fendif

Тип данных sem t

1-5 Мы реализуем именованный семафор Posix с помощью набора семафоров System V, состоящего из одного элемента. Структура данных семафора содержит идентификатор семафора System V и магическое число (обсуждавшееся в связи с листингом 10.21).

Функция sem open

в листинге 10.37 приведен текст первой половины функции semjpen, которая создает новый семафор или открывает существующий.

Листинг 10.37. Функция sem open: первая часть

my pxsem svsem/sem open.с

1 finclude unpipc.h

2 finclude semaphore.h

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

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

5 mysemj *

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

int i. fd. semflag. semid. save errno:

9 keyj key:

10 modej mode:

11 vajist ap:

12 mysemj *sem:

13 union semun arg:

14 unsigned int value:

15 struct semid ds seminfo:

16 struct sembuf initop:

17 /* режим доступа для sem open() без OJREAT не указывается: угадываем */

18 semflag = SVSEM MODE:

19 semid = -1:



20 if (ofiag & 0 CREAT) {

21 va start(ap. ofiag): /* инициализируем ap последним явно указанным

аргументом */

22 mode = va arg(ap. va mode t):

23 value = va arg(ap. unsigned int):

24 va end(ap):

25 /* преобразуем в ключ, который будет идентифицировать семафор System V */

26 if ( (fd = open(pathname, oflag. mode)) == -1)

27 return(SEM FAILED):

28 close(fd):

29 if ( (key = ftok(pathname. 0)) == (key t) -1)

30 return(SEM FAILED):

31 semflag = IPC CREAT (nrade & 0777):

32 if (oflag & OJXCL)

33 semflag = IPCJXCL:

34 /* создаем семафор System V с флагом IPCJXCL */

35 if ( (semid = semget(key. 1. semflag IPCJXCL)) >= 0) {

36 /* OK. мы успели первыми, поэтому инициализируем нулем */

37 arg.val = 0:

38 if (semctl(semid. 0. SETVAL. arg) = -1)

39 goto err:

40 /* увеличиваем значение, чтобы sem otime стало ненулевым */

41 if (value > SEMVMX) {

42 errno = EINVAL:

43 goto err:

44 }

45 in1top.sem num = 0:

46 1nitop.sem op = value:

47 ini top. sem Jig = 0:

48 if (semop(semid. &initop. 1) == -1)

49 goto err:

50 goto finish:

51 } else if (errno != EEXIST (semflag & IPCJXCL) != 0)

52 goto err:

53 /* иначе продолжаем выполнение */

54 }

Создание нового семафора и работа со списком аргументов переменной длины

20-24 Если вызвавший процесс указывает флаг OJREAT, мы знаем, что функции будут переданы четыре аргумента, а не два. Работа со списком аргументов переменной длины и типом данных va mode t обсуждалась в связи с листингом 5.17.

Создание вспомогательного файла и преобразование полного имени в ключ System V IPC

25-30 Создается обычный файл с именем, указываемым при вызове функции. Это делается для того, чтобы указать его имя при вызове функции ftok для последующей идентификации семафора. Аргумент of 1 ag, принятый от вызвавшего процесса, передается функции open для дополнительного файла, что позволяет создать его.



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