Π ΠΈΡ. 8.1. ΠΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π΄ΠΈΠ°Π³ΡΠ°ΠΌΠΌΠ° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈΠ· Π»ΠΈΡΡΠΈΠ½Π³Π° 8.9
10-13 Π‘ΠΎΠ·Π΄Π°ΡΡΡΡ Π΄Π²Π° ΠΏΠΎΡΠΎΠΊΠ°, ΠΏΠ΅ΡΠ²ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΡ thread1, Π° Π²ΡΠΎΡΠΎΠΉ β thread2. ΠΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ Π΄Π΅Π»Π°Π΅ΡΡΡ ΠΏΠ°ΡΠ·Π° Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡΡ Π² ΠΎΠ΄Π½Ρ ΡΠ΅ΠΊΡΠ½Π΄Ρ, ΡΡΠΎΠ±Ρ ΠΎΠ½ ΡΡΠΏΠ΅Π» Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°ΡΡ ΡΠ΅ΡΡΡΡ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅.
ΠΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²14-23 ΠΡ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π΅Π³ΠΎ ΡΡΠ°ΡΡΡ ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ PTHREAD_CANCEL. ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, ΡΡΠΎ Π΅Π³ΠΎ ΡΡΠ°ΡΡΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ Π½ΡΠ»Π΅Π²ΠΎΠΉ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ. ΠΠ°ΡΠ΅ΠΌ ΠΌΡ Π²ΡΠ²ΠΎΠ΄ΠΈΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅Ρ ΡΡΠ΅ΡΡΠΈΠΊΠΎΠ² Π² ΡΡΡΡΠΊΡΡΡΠ΅ pthread_rwlock_t ΠΈ ΡΠ½ΠΈΡΡΠΎΠΆΠ°Π΅ΠΌ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ.
ΠΠΈΡΡΠΈΠ½Π³ 8.9. Π’Π΅ΡΡΠΎΠ²Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°, ΠΈΠ»Π»ΡΡΡΡΠΈΡΡΡΡΠ°Ρ ΠΎΡΠΌΠ΅Π½Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠ°//my_rwlock_cancel/testcancel.Ρ
1 #include "unpipc.h"
2 #include "pthread_rwlock.h"
3 pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
4 pthread_t tid1, tid2;
5 void *thread1(void *), *thread2(void *);
6 int
7 main(int argc, char **argv)
8 {
9 void *status;
10 Set_concurrency(2);
11 Pthread_create(&tid1, NULL, thread1, NULL);
12 sleep(1); /* Π΄Π°Π΅ΠΌ ΠΏΠ΅ΡΠ²ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ */
13 Pthread_create(&tid2, NULL, thread2, NULL);
14 Pthread_join(tid2, &status);
15 if (status != PTHREAD_CANCELED)
16 printf("thread2 status = %p\n", status);
17 Pthread_join(tid1, &status);
18 if (status != NULL)
19 printf("thread1 status = %p\n", status);
20 printf("rw_refcount = %d, rw_nwaitreaders = %d, rw_nwaitwriters = %d\n",
21 rwlock.rw_refcount, rwlock.rw_nwaitreaders,
22 rwlock.rw_nwaitwriters);
23 Pthread_rwlock_destroy(&rwlock);
24 exit(0);
25 }
26 void *
27 thread1(void *arg)
28 {
29 Pthread_rwlock_rdlock(&rwlock);
30 printf("thread1() got a read lock\n");
31 sleep(3); /* Π΄Π°Π΅ΠΌ Π²ΡΠΎΡΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ pthread_rwlock_wrlock() */
32 pthread_cancel(tid2);
33 sleep(3);
34 Pthread_rwlock_unlock(&rwlock);
35 return(NULL);
36 }
37 void *
38 thread2(void *arg)
39 {
40 printf("thread2() trying to obtain a write lock\n"):
41 Pthread_rwlock_wrlock(&rwlock);
42 printf("thread2() got a write lock\n"); /* Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΎ */
43 sleep(1);
44 Pthread_rwlock_unlock(&rwlock);
45 return(NULL);
46 }
Π€ΡΠ½ΠΊΡΠΈΡ thread126-36 ΠΠΎΡΠΎΠΊ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΆΠ΄Π΅Ρ 3 ΡΠ΅ΠΊΡΠ½Π΄Ρ. ΠΡΠ° ΠΏΠ°ΡΠ·Π° Π΄Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π΄ΡΡΠ³ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ Π²ΡΠ·Π²Π°ΡΡ pthread_rwlock_wrlock ΠΈ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°ΡΡΡΡ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ pthread_cond_wait, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π½Π° Π·Π°ΠΏΠΈΡΡ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π° ΠΈΠ·-Π·Π° Π½Π°Π»ΠΈΡΠΈΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅. ΠΠ°ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π²ΡΠ·ΡΠ²Π°Π΅Ρ pthread_cancel Π΄Π»Ρ ΠΎΡΠΌΠ΅Π½Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°, ΠΆΠ΄Π΅Ρ 3 ΡΠ΅ΠΊΡΠ½Π΄Ρ, ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ Π·Π°Π²Π΅ΡΡΠ°Π΅Ρ ΡΠ°Π±ΠΎΡΡ.
Π€ΡΠ½ΠΊΡΠΈΡ thread237-46 ΠΡΠΎΡΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π΄Π΅Π»Π°Π΅Ρ ΠΏΠΎΠΏΡΡΠΊΡ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π½Π° Π·Π°ΠΏΠΈΡΡ (ΠΊΠΎΡΠΎΡΡΡ ΠΎΠ½ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΏΠ΅ΡΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ ΠΏΠΎΠ»ΡΡΠΈΠ» Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π½Π° ΡΡΠ΅Π½ΠΈΠ΅). ΠΡΡΠ°Π²ΡΠ°ΡΡΡ ΡΠ°ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π°.
ΠΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΡΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΠΉ ΠΈΠ· ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ ΡΠ°Π·Π΄Π΅Π»Π° ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ:
solaris % testcancel
thread1() got a read lock
thread2() trying to obtain a write lock
ΠΈ ΠΌΡ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²Π΅ΡΠ½Π΅ΠΌΡΡ ΠΊ ΠΏΡΠΈΠ³Π»Π°ΡΠ΅Π½ΠΈΡ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡΠ°. ΠΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Π·Π°Π²ΠΈΡΠ½Π΅Ρ. ΠΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ Π²ΠΎΡ ΡΡΠΎ:
1. ΠΡΠΎΡΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π²ΡΠ·Π²Π°Π» pthread_rwlock_wrlock (Π»ΠΈΡΡΠΈΠ½Π³ 8.6), ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ»Π° Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π° Π² Π²ΡΠ·ΠΎΠ²Π΅ pthread_cond_wait.
2. ΠΠ΅ΡΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π²Π΅ΡΠ½ΡΠ»ΡΡ ΠΈΠ· Π²ΡΠ·ΠΎΠ²Π° slΠ΅Π΅Ρ(3) ΠΈ Π²ΡΠ·Π²Π°Π» pthread_cancel.
3. ΠΡΠΎΡΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π±ΡΠ» ΠΎΡΠΌΠ΅Π½Π΅Π½ ΠΈ Π·Π°Π²Π΅ΡΡΠΈΠ» ΡΠ°Π±ΠΎΡΡ. ΠΡΠΈ ΠΎΡΠΌΠ΅Π½Π΅ ΠΏΠΎΡΠΎΠΊΠ°, Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ ΡΠΈΠ³Π½Π°Π»Π° ΠΏΠΎ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ Π²ΡΠ·ΠΎΠ²Π° ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°-ΠΎΡΠΈΡΡΠΈΡΠ΅Π»Ρ. (ΠΡ Π½Π΅ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π»ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ, Π½ΠΎ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π΄ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠ°.) Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, ΠΏΡΠΈ ΠΎΡΠΌΠ΅Π½Π΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΡΡΠ°Π»ΠΎΡΡ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π½ΡΠΌ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ rw_nwaitwriters Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 8.6 Π±ΡΠ»ΠΎ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ΠΎ.
4. ΠΠ΅ΡΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π²ΡΠ·ΡΠ²Π°Π΅Ρ pthread_rwlock_unlock ΠΈ Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π½Π°Π²ΡΠ΅Π³Π΄Π° ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ pthread_mutex_lock (Π»ΠΈΡΡΠΈΠ½Π³ 8.8), ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅ Π΅ΡΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΎ ΠΎΡΠΌΠ΅Π½Π΅Π½Π½ΡΠΌ ΠΏΠΎΡΠΎΠΊΠΎΠΌ.
ΠΡΠ»ΠΈ ΠΌΡ ΡΠ±Π΅ΡΠ΅ΠΌ Π²ΡΠ·ΠΎΠ² pthread_rwlock_unlock Π² ΡΡΠ½ΠΊΡΠΈΠΈ thread1, ΡΡΠ½ΠΊΡΠΈΡ main Π²ΡΠ²Π΅Π΄Π΅Ρ Π²ΠΎΡ ΡΡΠΎ:
rw_refcount = 1, rw_nwaitreaders = 0, rw_nwaitwriters = 1
pthread_rwlock_destroy error: Device busy
ΠΠ΅ΡΠ²ΡΠΉ ΡΡΠ΅ΡΡΠΈΠΊ ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ 1, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΌΡ ΡΠ΄Π°Π»ΠΈΠ»ΠΈ Π²ΡΠ·ΠΎΠ² pthread_rwlock_ unlock, Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΡΡΠ΅ΡΡΠΈΠΊ ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ 1, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ Π±ΡΠ» ΡΠ²Π΅Π»ΠΈΡΠ΅Π½ Π²ΡΠΎΡΡΠΌ ΠΏΠΎΡΠΎΠΊΠΎΠΌ Π΄ΠΎ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡΠΎΡ Π±ΡΠ» ΠΎΡΠΌΠ΅Π½Π΅Π½.
ΠΡΠΏΡΠ°Π²ΠΈΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΏΡΠΎΡΡΠΎ. Π‘Π½Π°ΡΠ°Π»Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΄Π²Π΅ ΡΡΡΠΎΠΊΠΈ ΠΊ ΡΡΠ½ΠΊΡΠΈΠΈ pthread_rwlock_rdlock Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 8.4. Π‘ΡΡΠΎΠΊΠΈ ΠΎΡΠΌΠ΅ΡΠ΅Π½Ρ Π·Π½Π°ΠΊΠΎΠΌ +:
rw->rw_nwaitreaders++;
+ pthread_cleanup_push(rwlock_cancelrdwait, (void *) rw);
result = pthread_cond_wait(&rw->rw_condreaders, &rw->rw_mutex);
+ pthread_cleanup_pop(0);
rw->rw_nwaitreaders++;
ΠΠ΅ΡΠ²Π°Ρ Π½ΠΎΠ²Π°Ρ ΡΡΡΠΎΠΊΠ° ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ-ΠΎΡΠΈΡΡΠΈΡΠ΅Π»Ρ (ΡΡΠ½ΠΊΡΠΈΡ rwlock_cancelrdwait), Π° Π΅Π³ΠΎ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ rw. ΠΠΎΡΠ»Π΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ΅Π½ΠΈΡ ΠΈΠ· pthread_cond_wait Π²ΡΠΎΡΠ°Ρ Π½ΠΎΠ²Π°Ρ ΡΡΡΠΎΠΊΠ° ΡΠ΄Π°Π»ΡΠ΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ. ΠΡΠ³ΡΠΌΠ΅Π½Ρ ΡΡΠ½ΠΊΡΠΈΠΈ pthread_cleanup_pop ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ-ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΏΡΠΈ ΡΡΠΎΠΌ Π²ΡΠ·ΡΠ²Π°ΡΡ Π½Π΅ ΡΠ»Π΅Π΄ΡΠ΅Ρ. ΠΡΠ»ΠΈ ΡΡΠΎΡ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ ΠΈΠΌΠ΅Π΅Ρ Π½Π΅Π½ΡΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π±ΡΠ΄Π΅Ρ ΡΠ½Π°ΡΠ°Π»Π° Π²ΡΠ·Π²Π°Π½, Π° Π·Π°ΡΠ΅ΠΌ ΡΠ΄Π°Π»Π΅Π½.
ΠΡΠ»ΠΈ ΠΏΠΎΡΠΎΠΊ Π±ΡΠ΄Π΅Ρ ΠΎΡΠΌΠ΅Π½Π΅Π½ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ pthread_cond_wait, Π²ΠΎΠ·Π²ΡΠ°ΡΠ° ΠΈΠ· Π½Π΅Π΅ Π½Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ. ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ Π±ΡΠ΄ΡΡ Π·Π°ΠΏΡΡΠ΅Π½Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ (ΠΏΠΎΡΠ»Π΅ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ, ΠΊΠ°ΠΊ ΠΌΡ ΠΎΡΠΌΠ΅ΡΠΈΠ»ΠΈ Π² ΠΏΡΠ½ΠΊΡΠ΅ 3 ΡΡΡΡ Π²ΡΡΠ΅).
Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 8.10 ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ ΡΠ΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ rwlock_cancelrdwait, ΡΠ²Π»ΡΡΡΠ΅ΠΉΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠΌ-ΠΎΡΠΈΡΡΠΈΡΠ΅Π»Π΅ΠΌ Π΄Π»Ρ phtread_rwlock_rdlock.
ΠΠΈΡΡΠΈΠ½Π³ 8.10. Π€ΡΠ½ΠΊΡΠΈΡ rwlock_cancelrdwait: ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΡΡΠ΅Π½ΠΈΡ//my_rwlock_cancel/pthread_rwlock_rdlock.Ρ
3 static void
4 rwlock_cancelrdwait(void *arg)
5 {
6 pthread_rwlock_t *rw;
7 rw = arg;
8 rw->rw_nwaitreaders--;
9 pthread_mutex_unlock(&rw->rw_mutex);
10 }
8-9 Π‘ΡΠ΅ΡΡΠΈΠΊ rw_nwaitreaders ΡΠΌΠ΅Π½ΡΡΠ°Π΅ΡΡΡ, Π° Π·Π°ΡΠ΅ΠΌ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅. ΠΡΠΎ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ Π²ΠΎΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½ΠΎ ΠΏΡΠΈ ΠΎΡΠΌΠ΅Π½Π΅ ΠΏΠΎΡΠΎΠΊΠ°.
ΠΠ½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΎ ΠΌΡ ΠΈΡΠΏΡΠ°Π²ΠΈΠΌ ΡΠ΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ pthread_rwlock_wrlock ΠΈΠ· Π»ΠΈΡΡΠΈΠ½Π³Π° 8.6. Π‘Π½Π°ΡΠ°Π»Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΄Π²Π΅ Π½ΠΎΠ²ΡΠ΅ ΡΡΡΠΎΠΊΠΈ ΡΡΠ΄ΠΎΠΌ Ρ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ pthread_cond_wait:
rw->rw_nwaitreaders++;
+ pthread_cleanup_push(rwlock_cancelrwrwait, (void*) rw);
result = pthread_cond_wait(&rw->rw_condwriters, &rw->rw_mutex);
+ pthread_cleanup_pop(0);
rw->rw_nwaitreaders--;
Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 8.11 ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ ΡΠ΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ rwlock_cancelwrwait, ΡΠ²Π»ΡΡΡΠ΅ΠΉΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠΌ-ΠΎΡΠΈΡΡΠΈΡΠ΅Π»Π΅ΠΌ Π΄Π»Ρ Π·Π°ΠΏΡΠΎΡΠ° Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π½Π° Π·Π°ΠΏΠΈΡΡ.
ΠΠΈΡΡΠΈΠ½Π³ 8.11. Π€ΡΠ½ΠΊΡΠΈΡ rwlock_cancelwrwait: ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π·Π°ΠΏΠΈΡΠΈ//my_rwlock_cancel/pthread_rwlock_wrlock.Ρ
3 static void
4 rwlock_cancelwrwait(void *arg)
5 {
6 pthread_rwlock_t *rw;
7 rw = arg;
8 rw->rw_nwaitwritersββ;
9 pthread_mutex_unlock(&rw->rw_mutex);
10 }
8-9 Π‘ΡΠ΅ΡΡΠΈΠΊ rw_nwaitwriters ΡΠΌΠ΅Π½ΡΡΠ°Π΅ΡΡΡ, ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ. ΠΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ Π½Π°ΡΠ΅ΠΉ ΡΠ΅ΡΡΠΎΠ²ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈΠ· Π»ΠΈΡΡΠΈΠ½Π³Π° 8.9 Ρ ΡΡΠΈΠΌΠΈ Π½ΠΎΠ²ΡΠΌΠΈ ΡΡΠ½ΠΊΡΠΈΡΠΌΠΈ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ:
solaris %testcancel
thread1() got a read lock
thread2() trying to obtain a write lock
rw_refcount = 0, rw_nwaitreaders = 0, rw_nwaitwriters = 0
Π’Π΅ΠΏΠ΅ΡΡ ΡΡΠΈ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΠΈΠΌΠ΅ΡΡ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΠΏΠ΅ΡΠ²ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΈΠ· Π²ΡΠ·ΠΎΠ²Π° pthread_rwlock_unlock, Π° ΡΡΠ½ΠΊΡΠΈΡ pthread_rwlock_destroy Π½Π΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΡ EBUSY.
ΠΠ ΠΠΠΠ§ΠΠΠΠ
ΠΡΠΎΡ ΡΠ°Π·Π΄Π΅Π» ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΠΎΠ±Π·ΠΎΡ Π²ΠΎΠΏΡΠΎΡΠΎΠ², ΡΠ²ΡΠ·Π°Π½Π½ΡΡ Ρ ΠΎΡΠΌΠ΅Π½ΠΎΠΉ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ². ΠΠ»Ρ Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΈΠ·ΡΡΠ΅Π½ΠΈΡ ΡΡΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊ ΡΠ°Π·Π΄Π΅Π»Ρ 5.3 ΠΊΠ½ΠΈΠ³ΠΈ [3].
8.6. Π Π΅Π·ΡΠΌΠ΅
ΠΠ»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΡΡΠ΅Π½ΠΈΡ-Π·Π°ΠΏΠΈΡΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π»ΡΡΡΠ΅ ΡΠ°ΡΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΠΈΡΡ ΡΠ°Π±ΠΎΡΡ Ρ Π΄Π°Π½Π½ΡΠΌΠΈ, ΡΠ΅ΠΌ ΠΎΠ±ΡΡΠ½ΡΠ΅ Π²Π·Π°ΠΈΠΌΠ½ΡΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ, Π΅ΡΠ»ΠΈ Π·Π°ΡΠΈΡΠ°Π΅ΠΌΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΡΠ°ΡΠ΅ ΡΡΠΈΡΡΠ²Π°ΡΡΡΡ, ΡΠ΅ΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΡΡ. Π€ΡΠ½ΠΊΡΠΈΠΈ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΡΡΠΈΠΌΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ°ΠΌΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ ΡΡΠ°Π½Π΄Π°ΡΡΠΎΠΌ Unix 98, ΠΈΡ ΠΌΡ ΠΈ ΠΎΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π² ΡΡΠΎΠΉ Π³Π»Π°Π²Π΅. ΠΠ½Π°Π»ΠΎΠ³ΠΈΡΠ½ΡΠ΅ ΠΈΠ»ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠ΅ ΠΈΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΡΠ²ΠΈΡΡΡΡ Π² Π½ΠΎΠ²ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ ΡΡΠ°Π½Π΄Π°ΡΡΠ° Posix. ΠΠΎ Π²ΠΈΠ΄Ρ ΡΡΠ½ΠΊΡΠΈΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Ρ ΡΡΠ½ΠΊΡΠΈΡΠΌ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΡΠΎ Π²Π·Π°ΠΈΠΌΠ½ΡΠΌΠΈ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡΠΌΠΈ (Π³Π»Π°Π²Π° 7).
ΠΠ»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ ΡΡΠ΅Π½ΠΈΡ-Π·Π°ΠΏΠΈΡΠΈ Π»Π΅Π³ΠΊΠΎ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π²Π·Π°ΠΈΠΌΠ½ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ ΠΈ ΡΡΠ»ΠΎΠ²Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ . ΠΡ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΠΏΡΠΈΠΌΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ. Π Π½Π°ΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ ΠΈΠΌΠ΅ΡΡ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ, Π½ΠΎ Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ Π΄ΡΡΠ³ΠΈΡ Π²Π΅ΡΡΠΈΡΡ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΎΡΠ΄Π°Π½ ΠΈ ΡΡΠΈΡΡΠ²Π°ΡΡΠΈΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ.
ΠΠΎΡΠΎΠΊΠΈ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΎΡΠΌΠ΅Π½Π΅Π½Ρ Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ Π² Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ, Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ ΠΏΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ pthread_cond_wait, ΠΈ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ Π½Π°ΡΠ΅ΠΉ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΌΡ ΡΠ±Π΅Π΄ΠΈΠ»ΠΈΡΡ, ΡΡΠΎ ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΌΠΎΠ³ΡΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ. Π Π΅ΡΠΈΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ²-ΠΎΡΠΈΡΡΠΈΡΠ΅Π»Π΅ΠΉ.
Π£ΠΏΡΠ°ΠΆΠ½Π΅Π½ΠΈΡ
1. ΠΠ·ΠΌΠ΅Π½ΠΈΡΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π² ΡΠ°Π·Π΄Π΅Π»Π΅ 8.4 ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ ΠΈΠΌΠ΅Π»ΠΈ ΡΡΠΈΡΡΠ²Π°ΡΡΠΈΠ΅, Π° Π½Π΅ Π·Π°ΠΏΠΈΡΡΠ²Π°ΡΡΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ.