Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

//my_rwlock/pthread_rwlock_destroy.с

1 #include "unpipc.h"

2 #include "pthread_rwlock.h"

3 int

4 pthread_rwlock_destroy(pthread_rwlock_t *rw)

5 {

6 if (rw->rw_magic != RW_MAGIC)

7 return(EINVAL);

8 if (rw->rw_refcount != 0 ||

9 rw->rw_nwaitreaders != 0 || rw->rw_nwaitwriters != 0)

10 return(EBUSY);

11 pthread_mutex_destroy(&rw->rw_mutex);

12 pthread_cond_destroy(&rw->rw_condreaders);

13 pthread_cond_destroy(&rw->rw_condwriters);

14 rw->rw_magic = 0;

15 return(0);

16 }

Функция 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.

Функция pthread_rwlock_tryrdlock

В листинге 8.5 показана наша реализация функции pthread_rwlock_tryrdlock, которая не вызывает приостановления вызвавшего ее потока.

Листинг 8.5. Функция pthread_rwlock_tryrdlock: попытка заблокировать ресурс для чтения

//my_rwlock/pthread_rwlock_tryrdlock.с

1 #include "unpipc.h"

2 #include "pthread_rwlock.h"

3 int

4 pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)

5 {

6 int result;

7 if (rw->rwjnagic != RW_MAGIC)

8 return(EINVAL);

9 if ((result = pthread_mutex_lock(&rw->rw_mutex)) != 0)

10 return(result);

11 if (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0)

12 result = EBUSY; /* блокировка установлена пишущим потоком или есть пишущие потоки, ожидающие освобождения ресурса */

  • Читать дальше
  • 1
  • ...
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: