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

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

Удостоверимся, что семафор проинициализирован

79-96 Мы должны подождать, пока семафор не будет проинициализирован (если несколько потоков пытаются создать семафор приблизительно одновременно). Для этого мы вызываем stat и проверяем биты разрешений файла (поле st mode структуры stat). Если бит user-execute снят, структура успешно проинициализирована.

Возврат кодов ошибок

97-108 При возникновении ошибки нужно аккуратно вернуть ее код.

Функция sem close

в листинге 10.30 приведен текст нашей функции sem cl ose, которая просто вызывает munmap для отображенного в память файла. Если вызвавший процесс продолжит пользоваться указателем, который был ранее возвращен sem open, он получит сигнал SIGSEGV.

Листинг 10.30. Функция sem close

/ /my pxsem niiiap/ sem c1 ose. с

1 finclude unpipc.h

2 finclude semaphore.h

3 int

4 iT\ysem c1ose(mysem t *sem)

6 if (sem->sem mag1c != SEM MAGIC) {

7 errno = EINVAL:

8 return(-l):

10 if (munmap(sem. sizeof(mysem t)) -= -1)

11 return(-l):

12 return(0):

13 }

Функция sem unlink

Текст функции sem unl ink приведен в листинге 10.31. Она просто удаляет файл, через который реализован данный семафор, вызывая функцию unl i nk.

Функция sem post

В листинге 10.32 приведен текст функции sem post, которая увеличивает значение семафора, возобновляя выполнение всех процессов, заблокированных в ожидании этого события.

Листинг 10.31. Функция sem unlink

iT\y pxsem mmap/sem unlink .с

1 finclude unpipc.h

2 finclude semaphore.h

3- int

4 mysem unlink(const char *pathname)



6 if (uniink(pathname) == -1)

7 return(-l)-.

8 return(O);

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

my pxsem niiiap/sem post. с

1 #inciude unpipc.h

2 finclude semaphore.h

3 int

4 mysem post(mysem t *sem)

6 int n:

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 if (sem->sem count - 0)

16 pthread cond signal(&sem->sem cond):

17 sem->sem count++;

18 pthread mutex unlock(&seir->sem mutex);

19 return(O);

20 }

11-18 Прежде чем работать со структурой, нужно заблокировать соответствующее взаимное исключение. Если значение семафора изменяется с О на 1, нужно вызвать pthread cond si gnal, чтобы возобновилось выполнение одного из процессов, зарегистрированных на уведомление по данной условной переменной.

Функция sem wait

в листинге 10.33 приведен текст функции semwait, которая ожидает изменения значения семафора с О на положительное, после чего уменьшает его на 1.

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

my pxsem mmap/sem wai t.с

1 finclude unpipc.h

2 finclude semaphore.h

3 int

4 mysem wait(mysem t *sem) Ь {

6 int n;

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

8 errno = EINVAL:

9 return(-l);

10 } продолжение



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

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

12 еггпо = П-.

13 return(-l)-.

14 }

15 while (sem->sem count == 0)

16 pthread cond wait(&sem->sem cond. &sem->sem mutex):

17 sem->sem count--:

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

19 return(O):

20 }

11-18 Прежде чем работать с семафором, нужно заблокировать соответствующее взаимное исключение. Если значение семафора О, выполнение процесса приостанавливается в вызове pthread cond wait до тех пор, пока другой процесс не вызовет pthread cond signal для этого семафора, изменив его значение с О на 1. После того как значение становится ненулевым, мы уменьшаем его на 1 и разблокируем взаимное исключение.

Функция sem trywait

в листинге 10.34 приведен текст функции semtrywait, которая представляет собой просто неблокируемый вариант функции semwait. 11-22 Мы блокируем взаимное исключение и проверяем значение семафора. Если оно положительно, мы вычитаем из него 1 и возвращаем вызвавшему процессу код 0. В противном случае возвращается -1, а переменной еггпо присваивается код ошибки EAGAIN.

Листинг 10.34. Функция semjrywait

/ /my pxsem niiiap/ sem Jrywai t. с

1 finclude unpipc.h

2 finclude semaphore.h

3 int

4 mysemjrywait(mysemj *sem)

6 1nt n, rc:

7 if (sem->sem mag1c != 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 if (sem->sem count > 0) {

16 sem->sem count--;

17 rc = 0:

18 } else {

19 rc - -1;

20 errno = EAGAIN;

21 }

22 pthread mutex unlock(&sem->sem mutex);

23 return(rc):

24 }



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