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

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

3 maindnt argc, char **argv)

5 if (argc !- 2)

6 err quit( usage: semunlink <name> ):

7 Sem unlink(argv[l]):

8 exit(O):

Программа semgetvalue

в листинге 10.5 приведен текст простейшей программы, которая открывает указанный именованный семафор, получает его текущее значение и выводит его.

Листинг 10.5. Получение и вывод значения семафора

pxsem/semgetvalue.с

1 linclude unpipc.h

2 int

3 main(int argc, char **argv)

5 sem t *sem:

6 int val:

7 if (argc != 2)

8 err quit( usage: semgetvalue <name> ):

9 sem = Sem open(argv[l]. 0):

10 Sem getvalue(sem. &val):

11 pri ntf ( value = %й\г) . val):

12 exit(O):

13 }

Открытие семафора

9 Семафор, который мы открываем, должен быть заранее создан другой программой. Вторым аргументом seffl open будет 0: мы не указываем флаг 0 CREAT и нам не нужно задавать никаких других параметров открытия 0 ххх.

Программа semwait

Программа в листинге 10.6 открывает именованный семафор, вызывает semwait (которая приостанавливает выполнение процесса, если значение семафора меньше либо равно О, а при положительном значении семафора уменьшает его на 1), получает и выводит значение семафора, а затем останавливает свою работу навсегда при вызове pause.

Листинг 10.6. Ожидание изменения значения семафора и вывод нового значения

pxsem/semwait.c

1 linclude unpipc.h

2 int

3 main(int argc, char **argv) продолжение



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

5 sem t *sem;

6 1nt val;

7 if (argc !- 2)

8 err quit( usage: semwait <name> );

9 sem = Sem open(argv[l], 0);

10 Sem wait(sem);

11 Sem getvalue(sem, &val):

12 printf( pid *ld has semaphore, value - *d\n , (long) getpidO, val):

13 pauseO; /* блокируется, пока не будет удален */

14 exit(O);

15 }

Программа sempost

в листинге 10,7 приведена программа, которая выполняет операцию post для указанного семафора (то есть увеличивает его значение на 1), а затем получает значение этого семафора и выводит его.

Листинг 10.7. Увеличение значения семафора

pxsem/sempost.c

1 linclude unpipc.h

2 int

3 main(int argc, char **argv)

5 sem t *sem;

6 int val;

7 if (argc != 2)

8 err quit( usage: sempost <name>);

9 sem - Sem open(argv[l], 0):

10 Sem post(sem):

11 Sem getvalue(sem, &val);

12 printf ( value = M\n , val):

13 exit(O);

14 }

Примеры

Для начала мы создадим именованный семафор в Digital Unix 4.0В и выведем его значение, устанавливаемое по умолчанию при инициализации:

alpha % semcreate /tmp/testl alpha * Is -1 /tmp/testl

-rw-r--r-- 1 rstevens system 264 Nov 13 08:51 /tmp/testl

alpha X semgetvalue /tmp/testl value = 1

Аналогично очередям сообщений Posix система создает файл семафора с тем именем, которое мы указали при вызове функции.



Теперь подождем изменения семафора и прервем работу программы, установившей блокировку:

alpha % semwait /tmp/testl

pid 9702 has semaphore, value = 0 значение после возврвтв из semj/ait

клавиша прерывания работы в нашей системе

alpha % semgetvalue /tmp/testl

value = О значение остается нулевым

Приведенный пример иллюстрирует упомянутые ранее особенности. Во-первых, значение семафора обладает живучестью ядра. Значение 1, установленное при создании семафора, хранится в ядре даже тогда, когда ни одна программа не пользуется этим семафором. Во-вторых, при выходе из программы semwait, заблокировавшей семафор, значение его не изменяется, то есть ресурс остается заблокированным. Это отличает семафоры от блокировок fcntl, описанных в главе 9, которые снимались автоматически при завершении работы процесса.

Покажем теперь, что в этой реализации отрицательное значение семафора используется для хранения информации о количестве процессов, ожидающих разблокирования семафора:

alpha % semgetvalue /tmp/testl

value = О зто значение сохранилось с конца предыдущего примера

alpha % semwait /tmp/testl & запуск в фоновом режиме

[1] 9718 блокируется в ожидании изменения значения семафора

alpha % semgetvalue /tmp/testl

value - -1 один процесс ожидает изменения семафора

alpha % semwait /tmp/testl & запуск еще одного процесса в фоновом режиме

[2] 9727 он также блокируется

alpha % semgetvalue /tmp/testl

value = -2 два процесса ожидают изменения семафора

alpha % sempost /tmp/testl

value = -1 значение после возвращения из semjpost

pid 9718 has semaphore, value = -1 вывод программы semait alpha % sempost /tmp/testl value - 0

pid 9727 has semaphore, value = 0 вывод программы semait

При первом вызове sempost значение семафора изменилось с -2 на -1 и один из процессов, ожидавших изменения значения семафора, был разблокирован.

Выполним те же действия в Solaris 2.6, обращая внимание на различия в реализации:

Solaris % semcreate /test2 Solaris % Is -1 /tmp/.*test2*

-rw-r-r-- 1 rstevens otherl 48 Nov 13 09:11 /tmp/.SEMDtest2

-rw-rw-rw- 1 rstevens otherl 0 Nov 13 09:11 /tmp/.SEMLtest2

Solaris % semgetvalue /test2 value = 1

Аналогично очередям сообщений Posix файлы создаются в каталоге /tmp, причем указываемое при вызове имя становится суффиксом имен файлов. Разрешения первого файла соответствуют указанным в вызове semopen, а второй файл, как можно предположить, используется для блокировки доступа.

Проверим, что ядро не осуществляет автоматического увеличения значения семафора при завершении работы процесса, установившего блокировку:



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