Главная страница Взаимодействие нетривиальных процессов Листинг 10.24 (продолжение) 6 return(unhnk(pathname)): Функция sem post в листинге 10.25 приведен текст функции sem post, которая увеличивает значение семафора. 11-12 Мы записываем один байт в FIFO. Если канал был пуст, это приведет к возобновлению выполнения всех процессов, заблокированных в вызове read для этого канала. Листинг 10.25. Функция sem post my pxsem fi fо/sem post.с 1 finclude unpipc.h 2 finclude semaphore.h 3 Int 4 iT\ysem post(mysem t *sem) 6 char c: 7 if (sem->sem mag1c !- SEM MAGIC) { 8 errno = EINVAL; 9 return(-l); 10 } 11 If (write(sem->sem fd[l]. &c, 1) == 1) 12 return(0); 13 return(-l); 14 } Функция sem wait Последняя функция для работы с именованными семафорами Posix - sem wait. Ее текст приведен в листинге 10.26. Листинг 10.26. Функция sem wait my pxsem f1fo/sem wa1t.с 1 finclude unpipc.h 2 finclude semaphore.h 3 int 4 mysem walt(mysem t *sem) 6 char c; 7 If (sem->sem mag1c != SEM MAGIC) { 8 errno = EINVAL: 9 return(-l); 10 } 11 If (read(sem->sem fd[0], &c. 1) == 1) 12 return(O): 13 return(-l): 14 } 11-12 Мы считываем 1 байт из канала FIFO, причем работа приостанавливается, если канал пуст. Мы еще не реализовали функцию sem trywait, но это можно сделать, установив флаг отключения блокировки для канала и используя обычный вызов read. Мы также не реализовали фзшкцию sem getval ue. В некоторых реализациях при вызове функции stat или fstat возвращается количество байтов в именованном или неименованном канале, причем оно помещается в поле st si ze структуры stat. Однако это не гарантируется стандартом Posix и, следовательно, не обязательно будет работать в других системах. Пример реализации этих двух функций для работы с семафорами Posix приведен в следующем разделе. 10.15. Реализация с помощью отображения в память Теперь займемся реализацией именованных семафоров Posix с помощью отображаемых в память файлов вместе со взаимными исключениями и условными переменными Posix. Реализация, аналогичная данной, приведена в разделе В. 11.3 Обоснования стандарта IEEE 1996 [8]. ПРИМЕЧАНИЕ - Отображаемые в память файлы описаны в главах 12 и 13. Данный раздел можно отложить, с тем чтобы вернуться к нему после прочтения этих глав. Прежде всего приведем текст нащего заголовочного файла semaphore.h (листинг 10.27), в котором определяется фундаментальный тип sem t. Тип sem t 1-7 Структура данных семафора содержит взаимное исключение, условную переменную и беззнаковое целое, в котором хранится текущее значение семафора. Как уже говорилось в связи с листингом 10.21, поле sem magi с получает значение SEM MAGIC при инициализации структуры. Листинг 10.27. Заголовочный файл semaphore.h / /my pxsem niiiap/ semaphore. h 1 /* фундаментальный тип */ 2 typedef struct { 3 pthread mutex t sem mutex: /* блокируется при проверке и изменении значения семафора */ 4 pthread cond t sem cond: /* при изменении нулевого значения */ 5 unsigned int sem count; /* значение семафора */ 6 int sem magic: /* магическое значение, если семафор открыт */ 7 } mysem t: 8 Idefine SEM MAGIC 0x67458923 9 #ifdef SEMJAILED 10 #undef SEMJAILED 11 #define SEMJAILED ((riysemj *)(-l)) /* чтобы избежать предупреждений компилятора */ 12 #endif Функция sem open в листинге 10.28 приведен текст первой части функции sem open, которая может использоваться для создания нового семафора или открытия существующего. Листинг 10.28. Функция sem open: первая половина my pxsem niiiap/sem open .с 1 finclude unpipc.h 2 finclude semaphore.h 3 finclude <stdarg.h> /* для списков аргументов переменной длины */ 4 fdefine MAX TRIES 10 /* количество попыток инициализации */ 5 mysem t * 6 mysem open(const char *pathname. int oflag; ... ) 8 int fd. 1. created. save errno: 9 mode t mode: 10 vajist ap: 11 mysem t *sem. semi nit: 12 struct stat statbuff: 13 unsigned int value: 14 pthread mutexattr t mattr: 15 pthread condattr t cattr: 16 created - 0: 17 sem - MAPJAILED; /* [sic] */ 18 again; 19 if (oflag & OJREAT) { 20 va start(ap. oflag): /* ap инициализируется последним явно указанным аргументом */ 21 mode = va arg(ap. vajrodej) & -SJXUSR: 22 value va arg(ap. unsigned int): 23 va end(ap): 24 /* открываем с указанием флага OJXCL и установкой бита user-execute */ 25 fd - open (pathname, oflag 0 EXCL OJDWR. mode SJXUSR): 26 if (fd < 0) { 27 if (errno == EEXIST && (oflag & OJXCL) == 0) 28 goto exists: /* уже существует. OK */ 29 else 30 return(SEMJAILED): 31 } 32 created - 1: 33 /* кто создает файл, тот его и инициализирует */ 34 /* установка размера файла */ 35 bzero(&sem1nit. sizeof(sem1n1t)): 36 if (wr1te(fd, &seminit. sizeof(semlnlt)) != sizeof(semlnlt)) 37 goto err: 38 /* отображение файла в память */ 39 sem = mmap(NULL. sizeof(mysemJ). PROTJEAD PROTJRITE. 40 MAPJHARED, fd. 0): 41 if (sem =- MAPJAILED) 42 goto err:
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |