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

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

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

//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; /* Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° установлСна ΠΏΠΈΡˆΡƒΡ‰ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ ΠΈΠ»ΠΈ Π΅ΡΡ‚ΡŒ ΠΏΠΈΡˆΡƒΡ‰ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ освобоТдСния рСсурса */

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_refcount Π² –1.

Листинг 8.6. Ѐункция pthread_rwlock_wrlock: ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π° запись

//my_rwlock/pthread_rwlock_wrlock.c

1  #include "unpipc.h"

2  #include "pthread_rwlock.h"


3  int

4  pthread_rwlock_wrlock(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  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 }

Ѐункция pthread_rwlock_trywrlock

НСблокируСмая функция pthread_rwlock_trywrlock ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 8.7.

11-14 Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика rw_refcount ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΎΡ‚ нуля, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΡƒΠΆΠ΅ установлСна ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ ΠΈΠ»ΠΈ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΌ процСссом (это Π±Π΅Π·Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎ) ΠΈ ΠΌΡ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ с ΠΊΠΎΠ΄ΠΎΠΌ EBUSY. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΠΌΡ‹ устанавливаСм Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Π½Π° запись, присвоив ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ rw_refcount Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ –1.

Листинг 8.7. Ѐункция pthread_rwlock_trywrlock: ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° получСния Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π° запись

//my_rwlock/pthread_rwlock_trywrlock.c

1  #include "unpipc.h"

2  #include "pthread_rwlock.h"


3  int

4  pthread_rwlock_trywrlock(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  if (rw->rw_refcount != 0)

12   result = EBUSY; /* Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ ΠΏΠΈΡˆΡƒΡ‰ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ ΠΈΠ»ΠΈ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΌ возмоТности записи */

13  else

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_unlock.c

1  #include "unpipc.h"

2  #include "pthread_rwlock.h"


3  int

4  pthread_rwlock_unlock(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  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_nwaitreaders > 0)

22   result = pthread_cond_broadcast(&rw->rw_condreaders);

23  pthread_mutex_unlock(&rw->rw_mutex);

24  return(result);

25 }

11-16 Если rw_refcount большС 0, ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ снимаСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅. Если rw_refcount Ρ€Π°Π²Π½ΠΎ –1, Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ снимаСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Π½Π° запись.

17-22 Если ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π° запись ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΏΠΎ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ rw_condwriters пСрСдаСтся сигнал (Ссли Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° свободна, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика rw_refcount Ρ€Π°Π²Π½ΠΎ 0). ΠœΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ запись, поэтому ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_cond_signal. Если Π½Π΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… возмоТности записи, Π½ΠΎ Π΅ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ возмоТности чтСния, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ pthread_cond_broadcast для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ rw_condreaders, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ считываниС нСсколькими ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ пСрСстаСм ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ для ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Ссли ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ возмоТности записи. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС постоянно ΠΏΠΎΡΠ²Π»ΡΡŽΡ‰ΠΈΠ΅ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΈ с запросами Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΉ возмоТности записи, ΠΆΠ΄Π°Ρ‚ΡŒ Ρ†Π΅Π»ΡƒΡŽ Π²Π΅Ρ‡Π½ΠΎΡΡ‚ΡŒ. По этой ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π΄Π²Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° if ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ просто:

/* ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚Π΅Π½ΠΈΠ΅ отдаСтся Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΌ процСссам */

if (rw->rw_nwaitreaders > 0 && rw->rw_refcount == 0)

 result = pthread_cond_signal(&rw->rw_condwriters);

else if (rw->rw_nwaitreaders > 0)

 result = pthread_cond_broadcast(&rw->rw_condreaders);

ΠœΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ rw->rw_refcount, Π½ΠΎ это ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌ pthread_cond_signal Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΠΏΠΎΡ‚Π΅Ρ€Π΅ эффСктивности.

8.5. ΠžΡ‚ΠΌΠ΅Π½Π° выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

ΠžΠ±ΡΡƒΠΆΠ΄Π°Ρ листинг 8.4, ΠΌΡ‹ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΠ»ΠΈ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅ΠΉ ΠΏΡ€ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π΅ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ pthread_cond_wait. Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_cancel, СдинствСнным Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ являСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½ΠΎ:

#include <pthread.h>

int pthread_cancel(pthread_t tid);

/* Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 0 Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π•Ρ…Ρ…Ρ… –в случаС ошибки */

ΠžΡ‚ΠΌΠ΅Π½Π° выполнСния ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использована Π² Ρ‚ΠΎΠΌ случаС, Ссли нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Π½Π°Π΄ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π·Π°Π΄Π°Ρ‡Π΅ΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, поиск записи Π² Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…) ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ… Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ Ρ€Π°Π½ΡŒΡˆΠ΅ всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ…. Π’ΠΎΠ³Π΄Π° ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈΡ… Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅. Π”Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ являСтся ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ошибки ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΡ… Π·Π°Π΄Π°Ρ‡Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Ρ‚Π΅ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈ всСх ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ….

Для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ выполнСния ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ (push) ΠΈΠ»ΠΈ ΡΠ½ΡΡ‚ΡŒ (pop) ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ-ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚Π΅Π»ΡŒ (cleanup handler):

#include <pthread.h>

void pthread_cleanup_push(void (*function) (void *) void *arg);

void pthread_cleanup_pop(int execute);

Π­Ρ‚ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ:

β–  Π² случаС ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ° (Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, Π²Ρ‹Π·Π²Π°Π²ΡˆΠΈΠΌ pthread_ cancel);

β–  Π² случаС Π΄ΠΎΠ±Ρ€ΠΎΠ²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ (Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ pthread_exit ΠΈΠ»ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠΌ ΠΈΠ· Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°).

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ-очиститСли Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ всю Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎ Π²ΠΎΡΡΡ‚Π°Π½ΠΎΠ²Π»Π΅Π½ΠΈΡŽ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Ρ‚Π°ΠΊΡƒΡŽ ΠΊΠ°ΠΊ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Π·Π°ΠΈΠΌΠ½Ρ‹Ρ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΈ сСмафоров, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ Π΄Π°Π½Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ.

АргумСнт function прСдставляСт собой адрСс Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° arg β€” Π΅Π΅ СдинствСнный Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. Ѐункция pthread_cleanup_pop всСгда удаляСт ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΈΠ· Π²Π΅Ρ€Ρ…ΡƒΡˆΠΊΠΈ стСка ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Ссли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ execute ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΎΡ‚ 0.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

ΠœΡ‹ снова встрСтимся с ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² связи с листингом 15.26, Π³Π΄Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΡ‚ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Π° выполнСния сСрвСра с Π΄Π²Π΅Ρ€ΡŒΠΌΠΈ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π² процСссС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π²Ρ‹Π·Π²Π°Π½Π½ΠΎΠΉ ΠΈΠΌ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹. 

ΠŸΡ€ΠΈΠΌΠ΅Ρ€

Π›Π΅Π³Ρ‡Π΅ всСго ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ нашСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ Ρ€Π°Π·Π΄Π΅Π»Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°. На рис. 8.1 ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π° врСмСнная Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° выполнСния нашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π° тСкст самой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 8.9. 

Рис. 8.1. ВрСмСнная Π΄ΠΈΠ°Π³Ρ€Π°ΠΌΠΌΠ° выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ· листинга 8.9