![]() |
![]() |
Главная страница Взаимодействие нетривиальных процессов 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, а второй файл, как можно предположить, используется для блокировки доступа. Проверим, что ядро не осуществляет автоматического увеличения значения семафора при завершении работы процесса, установившего блокировку:
|
© 2000 - 2025 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |