Главная страница Взаимодействие нетривиальных процессов Функция pthread rwlock tryrdlock в листинге 8.5 показана наша реализация функции pthread rwlock tryrdlock, которая не вызывает приостановления вызвавшего ее потока. Листинг 8.5. Функция pthread rwlock tryrdlock: попытка заблокировать ресурс для чтения my rwlock/pth read rwlock tryrdl ock.с 1 linclude unpipc.h 2 linclude pthread rwlock.h 3 int 4 pthread rwlock tryrdlock(pthread rwlock t *rw) 6 int result: 7 if (rw->rw magic != RW MAGIC) 8 return(EINVAL): 9 if ( (result = pthread mutexJock(&rw->rw mutex)) != 0) 10 return(result): 11 if (rw->rw refcount < 0 rw->rw nwaitwriters > 0) 12 result = EBUSY: /* блокировка установлена пишущим потоком или есть пишущие потоки, ожидающие освобождения ресурса */ 13 else 14 rw->rw refcount++: /* увеличение количества блокировок на чтение */ 15 pthread mutex unlock(&rw->rw mutex): 16 return(result): 17 } 11-14 Если блокировка в данный момент установлена на запись или есть процессы, ожидающие возможности установить ее на запись, возвращается ошибка с кодом EBUSY. В противном случае мы устанавливаем блокировку, увеличивая значение счетчика rw refcount. Функция pthread rwlock wrlock Текст функции pthread rwlock wrlock приведен в листинге 8,6. 11-17 Если ресурс заблокирован на считывание или запись (значение rw refcount отлично от 0), мы приостанавливаем выполнение потока. Для этого мы увеличиваем rw nwaitwriters и вызываем pthread cond wait с условной переменной rw condwriters. Для этой переменной посылается сигнал при снятии блокировки чтения-записи, если имеются ожидающие разрешения на запись процессы. 18-19 После получения блокировки на запись мы устанавливаем значение rw ref count в-1. Функция pthread rwlock trywrlock Неблокируемая функция pthread rwlock trywrlock показана в листинге 8.7. 11-14 Если значение счетчика rw refcount отлично от нуля, блокировка в данный момент уже установлена считывающим или записывающим процессом (это без- различно) и мы возвращаем ошибку с кодом EBUSY. В противном случае мы устанавливаем блокировку на запись, присвоив переменной rw refcount значение -1. Листинг 8.6. Функция pthread rwlock wrlock: получение блокировки на запись my rwlock/pth read rwlock wrlock.с 1 linclude unpipc.h 2 linclude pthread rwlock.h 3 int 4 pthread rwlock wrlock(pthread rwlock t *rw) 6 int result; 7 if (rw->rw magic != RW MAGIC) 8 return(EINVAL); 9 if ( (result = pthread mutex lock(&rw->rw mutex)) != 0) 10 return(result); 11 while (rw->rw refcount != 0) { 12 rw->rw nwaitwriters++; 13 result = pthread cond wait(&rw->rw condwriters. &rw->rw mutex): 14 rw->rw nwaitwriters--: 15 if (result != 0) 16 break: 17 } 18 if (result == 0) 19 rw->rw refcount = -1; 20 pthread mutex unlock(&rw->rw mutex); 21 return(result); 22 } Листинг 8.7. Функция pthread rwlock trywrlock: попытка получения блокировки на запись my rwlock/pthread rwlock trywrlock.с 1 linclude unpipc.h 2 linclude pthread rwlock.h 3 int 4 pthread rwlock trywrlock(pthread rwlock t *rw) 6 int result; 7 if (rw->rw magic != RW MAGIC) 8 return(EINVAL); 9 if ( (result = pthread mutex lock(&rw->rw mutex)) != 0) 10 return(result); 11 if (rw->rw refcount != 0) 12 result = EBUSY; /* заблокирован пишущим потоком или ожидающим возможности записи */ 13 else Листинг 8.7 (продолжение) 14 rw->rw refcount = -1; /* доступна */ 15 pthread mutex unlock(&rw->rw mutex); 16 return(result); 17 } Функция pthread rwlock unlock Последняя функция, pthread rwlock unlock, приведена в листинге 8.8. Листинг 8.8. Функция pthread rwlock unlock: разблокирование ресурса my rwlock/pthread rwlock unl ock.с 1 #include unpipc.h 2 linclude pthread rwlock.h 3 int 4 pthread rwlock unlock(pthread rwlock t *rw) 6 int result: 7 if (rw->rw magic != RW MAGIC) 8 return(EINVAL): 9 if ( (result = pthread mutex lock(&rw->rw mutex)) != 0) 10 return(result): 11 if (rw->rw refcount > 0) 12 rw->rw refcount--: /* снятие блокировки на чтение */ 13 else if (rw->rw refcount == -1) 14 rw->rw refcount = 0: /* снятие блокировки на запись */ 15 else 16 err dump( rw refcount = *d . rw->rw refcount); 17 /* преимущество отдается ожидающим возможности записи потокам */ 18 if (rw->rw nwaitwriters > 0) { 19 if (rw->rw refcount == 0) 20 result = pthread cond signal(&rw->rw condwriters): 21 } else if (rw->rw nwa.itreaders > 0) 22 result = pthread cond broadcast(&rw->rw condreaders): 23 pthread mutex unlock(&rw->rw mutex): 24 return(result): 25 } 11-16 Если rwrefcount больше 0, считывающий поток снимает блокировку на чтение. Если rwref count равно -1, записывающий поток снимает блокировку на запись. 17-22 Если имеются ожидающие разрешения на запись потоки, по условной переменной rwcondwri ters передается сигнал (если блокировка свободна, то есть значение счетчика rwrefcount равно 0). Мы знаем, что только один поток может осуществлять запись, поэтому используем функцию pthread cond signal. Если нет потоков, ожидающих возможности записи, но есть потоки, ожидающие возможности чтения, мы вызываем pthread cond broadcast для переменной rw condreaders, поскольку возможно одновременное считывание несколькими потоками. Обра-
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |