Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: взаимодСйствиС процСссов». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 47

Автор Уильям БтивСнс

Π’ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… pthread_rwlock_t

Π’ листингС 8.1[1] ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° pthread_rwlock .h, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ основной Ρ‚ΠΈΠΏ pthread_rwlock_t ΠΈ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… с Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌΠΈ чтСния ΠΈ записи. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ всС это находится Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ <pthread.h>.

Листинг 8.1. ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ… pthread_rwlock_t

//my_rwlock/pthread_rwlock.h

1  #ifndef __pthread_rwlock_h

2  #define __pthread_rwlock_h


3  typedef struct {

4   pthread_mutex_t rw_mutex; /* Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° для структуры */

5   pthread_cond_t rw_condreaders; /* для ΠΆΠ΄ΡƒΡ‰ΠΈΡ… Ρ‡ΠΈΡ‚Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

6   pthread_cond_t rw_condwriters; /* для ΠΆΠ΄ΡƒΡ‰ΠΈΡ… ΠΏΠΈΡˆΡƒΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

7   int rw_magic; /* для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ошибок */

8   int rw_nwaitreaders;/* число ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… */

9   int rw_nwaitwriters;/* число ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… */

10  int rw_refcount;

11  /* –1, Ссли Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π½Π° запись, ΠΈΠ½Π°Ρ‡Π΅ – количСство Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ */

12 } pthread_rwlock_t;


13 #define RW_MAGIC 0x19283746

14 /* порядок Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅, ΠΊΠ°ΠΊ Ρƒ элСмСнтов структуры */

15 #define PTHREAD_RWLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, \

16  PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, \

17  RW_MAGIC, 0, 0, 0 }


18 typedef int pthread_rwlockattr_t; /* Π½Π΅ поддСрТиваСтся */


19 /* ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ */

20 int pthread_rwlock_destroy(pthread_rwlock_t *);

21 int pthread_rwlock_init(pthread_rwlock_t *, pthread_rwlockattr_t *);

22 int pthread_rwlock_rdlock(pthread_rwlock_t *);

23 int pthread_rwlock_tryrdlock(pthread_rwlock_t *);

24 int pthread_rwlock_trywrlock(pthread_rwlock_t *);

25 int pthread_rwlock_unlock(pthread_rwlock_t *);

26 int pthread_rwlock_wrlock(pthread_rwlock_t *);


27 /* ΠΈ наши Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠΈ */

28 void pthread_rwlock_destroy(pthread_rwlock_t *);

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 ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ опрСдСляСм константу для статичСской ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ нашСй структуры.

Ѐункция pthread_rwlock_init

ΠŸΠ΅Ρ€Π²Π°Ρ функция, 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 }

Ѐункция pthread_rwlock destroy

Π’ листингС 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 ||

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);