Функция pthread_rwlock_rdlock
Функция pthread_rwlock_rdlock
Текст функции pthread_rwlock_rdlock приведен в листинге 8.4.
Листинг 8.4. Функция pthread_rwlock_rdlock: получение блокировки на чтение
//my_rwlock/pthread_rwlock_rdlock.с
1 #include "unpipc.h"
2 #include "pthread_rwlock.h"
3 int
4 pthread_rwlock_rdlock(pthread_rwlock_t *rw)
5 {
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 /* предпочтение отдается ожидающим разрешения на запись процессам */
12 while (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0) {
13 rw->rw_nwaitreaders++;
14 result = pthread_cond_wait(&rw->rw_condreaders, &rw->rw_mutex);
15 rw->rw_nwaitreaders--;
16 if (result != 0)
17 break;
18 }
19 if (result == 0)
20 rw->rw_refcount++; /* блокировка на чтение уже кем-то установлена */
21 pthread_mutex_unlock(&rw->rw_mutex);
22 return (result);
23 }
9-10 При работе со структурой pthread_rwl ock_t всегда устанавливается блокировка на rw_mutex, являющееся ее полем.
11-18 Нельзя получить блокировку на чтение, если rw_refcount имеет отрицательное значение (блокировка установлена на запись) или имеются потоки, ожидающие возможности получения блокировки на запись (rw_nwaitwriters больше 0). Если одно из этих условий верно, мы увеличиваем значение rw_nwaitreaders и вызываем pthread_cond_wait для условной переменной rw_condreaders. Вскоре мы увидим, что при разблокировании ресурса прежде всего проверяется наличие процессов, ожидающих возможности установить блокировку на запись, и если таковых не существует, проверяется наличие ожидающих возможности считывания. Если они имеются, для условной переменной rw_condreaders передается широковещательный сигнал.
19-20 При получении блокировки на чтение мы увеличиваем значение rw_refcount. Блокировка взаимного исключения после этого снимается.
ПРИМЕЧАНИЕ
В этой функции есть проблема: если вызвавший поток будет заблокирован в функции pthread_cond_wait и после этого его выполнение будет отменено, он завершит свою работу, не разблокировав взаимное исключение, и значение rw_nwaitreaders окажется неверным. Та же проблема есть и в функции pthread_rwlock_wrlock в листинге 8.6. Эти проблемы будут исправлены в разделе 8.5.
Данный текст является ознакомительным фрагментом.