Главная страница Взаимодействие нетривиальных процессов Тип данных sem t 1-5 Новая структура данных содержит два дескриптора, один из которых предназначен для чтения из FIFO, а другой - для записи. Для единообразия мы храним оба дескриптора в массиве из двух элементов, в котором первый дескриптор всегда открыт на чтение, а второй - на запись. Поле sem magic содержит значение SEM MAG1C, если структура проинициализирована. Это значение проверяется всеми функциями, которым передается указатель на тип sem t, чтобы гарантировать, что передан был действительно указатель на заранее инициализированную структуру, а не на произвольную область памяти. При закрытии семафора этому полю присваивается значение 0. Этот метод хотя и не совершенен, но дает возможность обнаружить некоторые ошибки при написании программ. Функция sem open в листинге 10.22 приведен текст функции sem open, которая создает новый семафор или открывает существующий. Листинг 10.22. Функция sem open niy pxsem f i f о/sem open. с 1 #include unpipc.h 2 finclude semaphore.h 3 finclude <stdarg.h> /* для произвольного списка аргументов */ 4 mysem t * 5 mysem open(const char *pathname. int oflag. ... ) 7 int i. flags. save errno; 8 char c: 9 nrade t mode: 10 vajist ap: 11 mysem t *sem: 12 unsigned int value: 13 if (oflag & 0 CREAT) { 14 va start(ap. oflag): /* ap инициализируется последним аргументом */ 15 mode - va arg(ap. va nrade t): 16 value = va arg(ap. unsigned int): 17 va end(ap): 18 if (mkfifo(pathname, nrade) < 0) { 19 if (errno =- EEXIST && (oflag & OJXCL) == 0) 20 oflag &- -OJREAT: /* уже существует. OK */ 21 else 22 return(SEMJAILED): 23 } 24 } 25 if ( (sem = manoc(sizeof(mysemJ))) == NULL) 26 return(SEM JAILED); 27 sem->semjd[0] = sem->semjd[l] = -1: 28 if ( (sem->sem fd[0] = open (pathname. 0 RDONLY 0 NONBLOCK)) < 0) ~ ~ продолжение 6 Листинг 10.22 (продолжение)
Создание нового семафора 13-17 Если при вызове указан флаг 0 CREAT, должно быть указано четыре аргумента, а не два. Мы вызываем va start, после чего переменная ар указывает на последний явно указанный аргумент (of 1 ад). Затем мы используем ар и функцию va arg для получения значений третьего и четвертого аргументов. Работу со списком аргументов переменной длины и использование нашего типа va mode t мы обсуждали в связи с листингом 5.17. Создание нового канала FIFO 18-23 Создается новый канал FIFO, имя которого было указано при вызове функции. Как мы отмечали в разделе 4.6, эта функция возвращает ошибку EEXIST, если канал уже существует. Если при вызове sem open флаг 0 EXCL не был указан, мы пропускаем эту ошибку; но нам не нужно будет инициализировать этот канал, так что мы при этом сбрасываем флаг 0 CREAT. Выделение памяти подтип sem t и открытие FIFO на чтение и запись 25-37 Мы выделяем место для типа sem t, который содержит два дескриптора. Затем мы дважды открываем канал FIFO: один раз только на чтение, а другой - только на запись. При этом мы не хотим блокирования при вызове open, поэтому указываем флаги 0 NONBLOCK при открытии очереди только для чтения (вспомните табл. 4.1). Мы также указываем флаг 0 NONBLOCK при открытии канала на запись, но это предназначено для обнаружения переполнения (на тот случай, если мы попытаемся записать больше, чем позволяет PIPE BUF). После открытия канала мы отключаем неблокируемый режим для дескриптора, открытого на чтение. Инициализация значения созданного семафора 38-42 Если мы создали семафор, его нужно проинициализировать, записав в канал FIFO val ue байтов. Если указанное при вызове значение val ue превышает определенное реализацией ограничение PIPE BUF, вызов write после переполнения FIFO вернет ошибку с кодом EAGAIN. Функция sem close Текст функции sem close приведен в листинге 10.23. 11-15 Мы закрываем оба дескриптора и освобождаем память, выделенную под тип sem t. Листинг 10.23. Функция sem close my pxsem fi fo/sem close.с 1 finclude unpipc.h 2 finclude semaphore.h 3 int 4 mysem close(mysem t *sem) 6 if (sem->sem magic 1= SEM MAGIC) { 7 errno = EINVAL: 8 return(-l): 10 sem->sem magic - 0: /* чтобы семафор нельзя было больше использовать */ 11 if (close(sem->sem fd[0]) == -1 close(sem->sem fd[l]) == -1) { 12 free(sem): 13 return(-1): 14 } 15 free(sem): 16 return(O): 17 } Функция sem unlink Функция sem unl ink, текст которой приведен в листинге 10.24, удаляет из файловой системы наш семафор. Она просто вызывает unl ink. Листинг 10.24. Функция sem unlink my pxsem fi fо/sem un1i n к.с 1 finclude unpipc.h 2 finclude semaphore.h 3 int 4 mysem unlink(const char *pathname) 5 { продолжение
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |