Главная страница Взаимодействие нетривиальных процессов Функция 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 для дополнительного файла, что позволяет создать его.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |