29 void pthread_rwlock_init(pthread_rwlock_t*, pthread_rwlockattr_t *);

30 void Pthread_rwlock_rdlock(pthread_rwlock_t *);

31 int Pthread_rwlock_tryrdlock(pthread_rwlock_t *);

32 int pthread_rwlock_trywrlock(pthread_rwlock_t *);

33 void pthread_rwlock_unlock(pthread_rwlock_t *);

34 void pthread_rwlock_wrlock(pthread_rwlock_t *);

35 #endif __pthread_rwlock_h

3-13 Наш тип pthread_rwlock_t содержит одно взаимное исключение, две условные переменные, один флаг и три счетчика. Мы увидим, для чего все это нужно, когда будем разбираться с работой функций нашей программы. При просмотре или изменении содержимого этой структуры мы должны устанавливать блокировку rw_mutex. После успешной инициализации структуры полю rw_magic присваивается значение RW_MAGIC. Значение этого поля проверяется всеми функциями — таким образом гарантируется, что вызвавший поток передал указатель на проинициализированную блокировку. Оно устанавливается в 0 после уничтожения блокировки.

Обратите внимание, что в счетчике rw_refcount всегда хранится текущий статус блокировки чтения-записи: –1 обозначает блокировку записи (и только одна такая блокировка может существовать в любой момент времени), 0 обозначает, что блокировка доступна и может быть установлена, а любое положительное значение соответствует количеству установленных блокировок на чтение.

14-17 Мы также определяем константу для статической инициализации нашей структуры.

<p>Функция pthread_rwlock_init</p>

Первая функция, pthread_rwlock_init, динамически инициализирует блокировку чтения-записи. Ее текст приведен в листинге 8.2.

7-8 Присваивание атрибутов с помощью этой функции не поддерживается, поэтому мы проверяем, чтобы указатель attr был нулевым.

9-19 Мы инициализируем взаимное исключение и две условные переменные, которые содержатся в нашей структуре. Все три счетчика устанавливаются в 0, а полю rw_magiс присваивается значение, указывающее на то, что структура была проинициализирована.

20-25 Если при инициализации взаимного исключения или условной переменной возникает ошибка, мы аккуратно уничтожаем проинициализированные объекты и возвращаем код ошибки.

Листинг 8.2. Функция pthread_rwlock_init: инициализация блокировки чтения-записи

//my_rwlock/pthread_rwlock_init.с

1  #include "unpipc.h"

2  #include "pthread_rwlock.h"

3  int

4  pthread_rwlock_init(pthread_rwlock_t *rw, pthread_rwlockattr_t *attr)

5  {

6   int result;

7   if (attr != NULL)

8    return(EINVAL); /* not supported */

9   if ((result = pthread_mutex_init(rw-rw_mutex, NULL)) != 0)

10   goto err1;

11  if ((result = pthread_cond_init(rw-rw_condreaders, NULL)) != 0)

12   goto err2;

13  if ((result = pthread_cond_init(rw-rw_condwriters, NULL)) != 0)

14   goto err3;

15  rw-rw_nwaitreaders = 0;

16  rw-rw_nwaitwriters = 0;

17  rw-rw_refcount = 0;

18  rw-rw_magic = RW_MAGIC;

19  return(0);

20 err3:

21  pthread_cond_destroy(rw-rw_condreaders);

22 err2;

23  pthread_mutex_destroy(rw-rw_mutex);

24 err1:

25  return(result); /* значение errno */

26 }

<p>Функция pthread_rwlock destroy</p>

В листинге 8.3 приведена функция pthread_rwlock_destroy, уничтожающая блокировку чтения записи после окончания работы с ней.

8-13 Прежде всего проверяется, не используется ли блокировка в данный момент, а затем вызываются соответствующие функции для уничтожения взаимного исключения и двух условных переменных.

Листинг 8.З. Функция pthread_rwlock_destroy: уничтожение блокировки чтения-записи

//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 ||

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже