Главная страница Взаимодействие нетривиальных процессов Удостоверимся, что семафор проинициализирован 79-96 Мы должны подождать, пока семафор не будет проинициализирован (если несколько потоков пытаются создать семафор приблизительно одновременно). Для этого мы вызываем stat и проверяем биты разрешений файла (поле st mode структуры stat). Если бит user-execute снят, структура успешно проинициализирована. Возврат кодов ошибок 97-108 При возникновении ошибки нужно аккуратно вернуть ее код. Функция sem close в листинге 10.30 приведен текст нашей функции sem cl ose, которая просто вызывает munmap для отображенного в память файла. Если вызвавший процесс продолжит пользоваться указателем, который был ранее возвращен sem open, он получит сигнал SIGSEGV. Листинг 10.30. Функция sem close / /my pxsem niiiap/ sem c1 ose. с 1 finclude unpipc.h 2 finclude semaphore.h 3 int 4 iT\ysem c1ose(mysem t *sem) 6 if (sem->sem mag1c != SEM MAGIC) { 7 errno = EINVAL: 8 return(-l): 10 if (munmap(sem. sizeof(mysem t)) -= -1) 11 return(-l): 12 return(0): 13 } Функция sem unlink Текст функции sem unl ink приведен в листинге 10.31. Она просто удаляет файл, через который реализован данный семафор, вызывая функцию unl i nk. Функция sem post В листинге 10.32 приведен текст функции sem post, которая увеличивает значение семафора, возобновляя выполнение всех процессов, заблокированных в ожидании этого события. Листинг 10.31. Функция sem unlink iT\y pxsem mmap/sem unlink .с 1 finclude unpipc.h 2 finclude semaphore.h 3- int 4 mysem unlink(const char *pathname) 6 if (uniink(pathname) == -1) 7 return(-l)-. 8 return(O); Листинг 10.32. Функция sem post my pxsem niiiap/sem post. с 1 #inciude unpipc.h 2 finclude semaphore.h 3 int 4 mysem post(mysem t *sem) 6 int n: 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 if (sem->sem count - 0) 16 pthread cond signal(&sem->sem cond): 17 sem->sem count++; 18 pthread mutex unlock(&seir->sem mutex); 19 return(O); 20 } 11-18 Прежде чем работать со структурой, нужно заблокировать соответствующее взаимное исключение. Если значение семафора изменяется с О на 1, нужно вызвать pthread cond si gnal, чтобы возобновилось выполнение одного из процессов, зарегистрированных на уведомление по данной условной переменной. Функция sem wait в листинге 10.33 приведен текст функции semwait, которая ожидает изменения значения семафора с О на положительное, после чего уменьшает его на 1. Листинг 10.33. Функция sem wait my pxsem mmap/sem wai t.с 1 finclude unpipc.h 2 finclude semaphore.h 3 int 4 mysem wait(mysem t *sem) Ь { 6 int n; 7 if (sem->sem magic != SEM MAGIC) { 8 errno = EINVAL: 9 return(-l); 10 } продолжение Листинг 10.33 (продолжение) 11 if ( (п = pthread mutexJock(&sem->sem mutex)) != 0) { 12 еггпо = П-. 13 return(-l)-. 14 } 15 while (sem->sem count == 0) 16 pthread cond wait(&sem->sem cond. &sem->sem mutex): 17 sem->sem count--: 18 pthread mutex unlock(&sem->sem mutex): 19 return(O): 20 } 11-18 Прежде чем работать с семафором, нужно заблокировать соответствующее взаимное исключение. Если значение семафора О, выполнение процесса приостанавливается в вызове pthread cond wait до тех пор, пока другой процесс не вызовет pthread cond signal для этого семафора, изменив его значение с О на 1. После того как значение становится ненулевым, мы уменьшаем его на 1 и разблокируем взаимное исключение. Функция sem trywait в листинге 10.34 приведен текст функции semtrywait, которая представляет собой просто неблокируемый вариант функции semwait. 11-22 Мы блокируем взаимное исключение и проверяем значение семафора. Если оно положительно, мы вычитаем из него 1 и возвращаем вызвавшему процессу код 0. В противном случае возвращается -1, а переменной еггпо присваивается код ошибки EAGAIN. Листинг 10.34. Функция semjrywait / /my pxsem niiiap/ sem Jrywai t. с 1 finclude unpipc.h 2 finclude semaphore.h 3 int 4 mysemjrywait(mysemj *sem) 6 1nt n, rc: 7 if (sem->sem mag1c != 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 if (sem->sem count > 0) { 16 sem->sem count--; 17 rc = 0: 18 } else { 19 rc - -1; 20 errno = EAGAIN; 21 } 22 pthread mutex unlock(&sem->sem mutex); 23 return(rc): 24 }
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |