59-62 ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π²ΡΠ΅Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΌΠ°ΡΡΠΈΠ²Π° ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΠ°ΠΊ ΡΠΆΠ΅ Π³ΠΎΠ²ΠΎΡΠΈΠ»ΠΎΡΡ, ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Π² Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠΌ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ΅ ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π²ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ-ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΠΈ Π·Π°Π²Π΅ΡΡΠ°Ρ ΡΠ²ΠΎΡ ΡΠ°Π±ΠΎΡΡ, ΡΠ°ΠΊ ΡΡΠΎ Π½Π°Π΄ΠΎΠ±Π½ΠΎΡΡΡ Π² ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΎΡΡΡΡΡΡΠ²ΡΠ΅Ρ.
ΠΡΠΈ Π·Π°ΠΏΡΡΠΊΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ ΠΎΠΏΠΈΡΠ°Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Ρ ΠΏΡΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠ°ΠΌΠΈ-ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΠΌΠ΅ΡΡΠ΅ ΡΠΎΠ·Π΄Π°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² Π΄Π°Π½Π½ΡΡ , ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ:
solaris % prodcons2 1000000 5
count[0] = 167165
count[1] = 249891
count[2] = 194221
count[3] = 191815
count[4] = 196908
ΠΠ°ΠΊ ΠΌΡ ΠΎΡΠΌΠ΅ΡΠ°Π»ΠΈ ΡΠ°Π½Π΅Π΅, Π΅ΡΠ»ΠΈ ΡΠ±ΡΠ°ΡΡ Π²ΡΠ·ΠΎΠ² set_concurrency, Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ Solaris 2.6 Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ count[0] Π±ΡΠ΄Π΅Ρ 1000000, Π° Π²ΡΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠΈ Π±ΡΠ΄ΡΡ Π½ΡΠ»Π΅Π²ΡΠΌΠΈ.
ΠΡΠ»ΠΈ ΡΠ±ΡΠ°ΡΡ ΠΈΠ· ΡΡΠΎΠ³ΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠ° Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ, ΠΎΠ½ ΠΏΠ΅ΡΠ΅ΡΡΠ°Π½Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ, ΠΊΠ°ΠΊ ΠΈ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ. ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² buff[i], Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊΠΎΡΠΎΡΡΡ Π±ΡΠ΄ΡΡ ΠΎΡΠ»ΠΈΡΠ½Ρ ΠΎΡ i. Π’Π°ΠΊΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ, Π΅ΡΠ»ΠΈ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡΠΎΠΊ.
7.4. ΠΠ»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° ΠΈ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅
ΠΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅ΠΌ ΡΠ΅ΠΏΠ΅ΡΡ, ΡΡΠΎ Π²Π·Π°ΠΈΠΌΠ½ΡΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Ρ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π½ΠΎ Π½Π΅ Π΄Π»Ρ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ. ΠΠ·ΠΌΠ΅Π½ΠΈΠΌ Π½Π°Ρ ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΠ· ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ ΡΠ°Π·Π΄Π΅Π»Π° ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ Π·Π°ΠΏΡΡΠΊΠ°Π»ΡΡ ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΠΎΡΠ»Π΅ Π·Π°ΠΏΡΡΠΊΠ° Π²ΡΠ΅Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ. ΠΡΠΎ Π΄Π°ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎ ΠΌΠ΅ΡΠ΅ ΠΈΡ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠΌΠΈ Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏpoΠ³ΡaΠΌΠΌΡ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 7.1, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ Π½Π΅ Π·Π°ΠΏΡΡΠΊΠ°Π»ΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π²ΡΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΠΈ Π½Π΅ Π·Π°Π²Π΅ΡΡΠ°Π»ΠΈ ΡΠ²ΠΎΡ ΡΠ°Π±ΠΎΡΡ. Π’Π΅ΠΏΠ΅ΡΡ Π½Π°ΠΌ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠΌΠΈ, ΡΡΠΎΠ±Ρ ΠΏΠ΅ΡΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π» ΡΠΎΠ»ΡΠΊΠΎ Π΄Π°Π½Π½ΡΠ΅, ΡΠΆΠ΅ ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌΠΈ.
Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 7.3 ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ ΡΠ΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ main. ΠΠ°ΡΠ°Π»ΠΎ ΠΊΠΎΠ΄Π° (Π΄ΠΎ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΈ main) Π½Π΅ ΠΏΡΠ΅ΡΠ΅ΡΠΏΠ΅Π»ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΏΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Ρ Π»ΠΈΡΡΠΈΠ½Π³ΠΎΠΌ 7.1.
ΠΠΈΡΡΠΈΠ½Π³ 7.3. Π€ΡΠ½ΠΊΡΠΈΡ main: Π·Π°ΠΏΡΡΠΊ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΡΡΠ°Π·Ρ ΠΏΠΎΡΠ»Π΅ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ//mutex/prodcons3.c
14 int
15 main(int argc, char **argv)
16 {
17 int i, nthreads, count[MAXNTHREADS];
18 pthread_t tid_produce[MAXNTHREADS], tid_consume;
19 if (argc != 3)
20 err_quit("usage: prodcons3 <#items> <#threads>");
21 nitems = min(atoi(argv[1]), MAXNITEMS);
22 nthreads = min(atoi(argv[2]), MAXNTHREADS);
23 /* ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π²ΡΠ΅Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ */
24 Set_concurrency(nthreads + 1);
25 for (i = 0; i < nthreads; i++) {
26 count[i] = 0;
27 Pthread_create(&tid_produce[i], NULL, produce, &count[i]);
28 }
29 Pthread_create(&tid_consume, NULL, consume, NULL);
30 /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ ΠΈ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ */
31 for (i = 0; i < nthreads; i++) {
32 Pthread_join(tid_produce[i], NULL);
33 printf("count[%d] = %d\n", i, count[i]);
34 }
35 Pthread_join(tid_consume, NULL);
36 exit(0);
37 }
24 ΠΡ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΠΌ ΡΡΠΎΠ²Π΅Π½Ρ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡΡ, ΡΡΠΎΠ±Ρ ΡΡΠ΅ΡΡΡ ΠΏΠΎΡΠΎΠΊ-ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ, Π²ΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΡΠΉ ΠΏΠ°ΡΠ°Π»Π»Π΅Π»ΡΠ½ΠΎ Ρ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠΌΠΈ.
25-29 ΠΠΎΡΠΎΠΊ-ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²-ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ.
Π€ΡΠ½ΠΊΡΠΈΡ produce ΠΏΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Ρ Π»ΠΈΡΡΠΈΠ½Π³ΠΎΠΌ 7.2 Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΡΡΡ. Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 7.4 ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ ΡΠ΅ΠΊΡΡ ΡΡΠ½ΠΊΡΠΈΠΈ consume, Π²ΡΠ·ΡΠ²Π°ΡΡΠ΅ΠΉ Π½ΠΎΠ²ΡΡ ΡΡΠ½ΠΊΡΠΈΡ consume_wait.
ΠΠΈΡΡΠΈΠ½Π³ 7.4. Π€ΡΠ½ΠΊΡΠΈΠΈ consume ΠΈ consume_wait//mutex/prodcons3.Ρ
54 void
55 consume wait(int i)
56 {
57 for (;;) {
58 Pthread_mutex_lock(&shared.mutex);
59 if (i < shared.nput) {
60 Pthread_mutex_unlock(&shared.mutex);
61 return; /* ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π³ΠΎΡΠΎΠ² */
62 }
63 Pthread_mutex_unlock(&shared.mutex);
64 }
65 }
66 void *
67 consume(void *arg)
68 {
69 int i;
70 for (i = 0; i < nitems; i++) {
71 consume_wait(i);
72 if (shared.buff[i] != i)
73 printf("buff[%d] = %d\n", i, shared.buff[i]);
74 }
75 return(NULL);
76 }
ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΆΠ΄Π°ΡΡ71 ΠΠ΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π² ΡΡΠ½ΠΊΡΠΈΠΈ consume Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π²ΡΠ·ΠΎΠ²Π° consume_wait ΠΏΠ΅ΡΠ΅Π΄ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΎΠΉ ΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΌΠ°ΡΡΠΈΠ²Π°.
ΠΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ57-64 ΠΠ°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ consume_wait Π΄ΠΎΠ»ΠΆΠ½Π° ΠΆΠ΄Π°ΡΡ, ΠΏΠΎΠΊΠ° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΠΈ Π½Π΅ ΡΠΎΠ·Π΄Π°Π΄ΡΡ i-ΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ. ΠΠ»Ρ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ ΡΡΠΎΠ³ΠΎ ΡΡΠ»ΠΎΠ²ΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ i ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΡΡΡ Ρ ΠΈΠ½Π΄Π΅ΠΊΡΠΎΠΌ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Ρ nput. ΠΠ»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ°, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ nput ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΎ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΉ Π² ΠΌΠΎΠΌΠ΅Π½Ρ Π΅Π³ΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ.
ΠΠ»Π°Π²Π½Π°Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° β ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ, Π΅ΡΠ»ΠΈ Π½ΡΠΆΠ½ΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ Π΅ΡΠ΅ Π½Π΅ Π³ΠΎΡΠΎΠ². ΠΡΠ΅, ΡΡΠΎ Π½Π°ΠΌ ΠΎΡΡΠ°Π΅ΡΡΡ ΠΈ ΡΡΠΎ ΠΌΡ Π΄Π΅Π»Π°Π΅ΠΌ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 7.4, β ΡΡΠΎ ΠΏΠΎΠ²ΡΠΎΡΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π² ΡΠΈΠΊΠ»Π΅, ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Ρ ΠΈ ΡΠ½ΠΈΠΌΠ°Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ½Π΄Π΅ΠΊΡΠ°. ΠΡΠΎ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ ΠΎΠΏΡΠΎΡΠΎΠΌ (spinning ΠΈΠ»ΠΈ polling) ΠΈ ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈΡΠ½Π΅ΠΉ ΡΡΠ°ΡΠΎΠΉ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°.
ΠΡ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ ΠΏΡΠΈΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡΠΎΡΠ΅ΡΡΠ° Π½Π° Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠ΅ΠΌΡ, Π½ΠΎ ΠΌΡ Π½Π΅ Π·Π½Π°Π΅ΠΌ, Π½Π° ΠΊΠ°ΠΊΠΎΠ΅. Π§ΡΠΎ Π½Π°ΠΌ Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠ΅Π»ΡΠ½ΠΎ Π½ΡΠΆΠ½ΠΎ β ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΠ°ΠΊΠΎΠ΅-ΡΠΎ Π΄ΡΡΠ³ΠΎΠ΅ ΡΡΠ΅Π΄ΡΡΠ²ΠΎ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠ΅Π΅ ΠΏΠΎΡΠΎΠΊΡ ΠΈΠ»ΠΈ ΠΏΡΠΎΡΠ΅ΡΡΡ ΠΏΡΠΈΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ ΡΠ°Π±ΠΎΡΡ, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ ΡΠΎΠ±ΡΡΠΈΠ΅.
7.5. Π£ΡΠ»ΠΎΠ²Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅: ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ ΠΈ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·Π°ΡΠΈΡ
ΠΠ·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π° ΡΡΠ»ΠΎΠ²Π½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ β Π΄Π»Ρ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ. ΠΡΠΎ Π΄Π²Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ ΡΡΠ΅Π΄ΡΡΠ²Π° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ, ΠΈ ΠΎΠ±Π° ΠΎΠ½ΠΈ Π½ΡΠΆΠ½Ρ. Π£ΡΠ»ΠΎΠ²Π½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΠΈΠΏΠ° pthread_cond_t. ΠΠ»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΡΠ°ΠΊΠΈΠΌΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Ρ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ:
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr, pthread_m_tex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
/* ΠΠ±Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ 0 Π² ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ, ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΡ Ρ Ρ β Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ */
Π‘Π»ΠΎΠ²ΠΎ signal Π² ΠΈΠΌΠ΅Π½ΠΈ Π²ΡΠΎΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΡ ΠΊ ΡΠΈΠ³Π½Π°Π»Π°ΠΌ Unix SIGxxx.
ΠΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΡΡΠ»ΠΎΠ²ΠΈΠ΅, ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΡ ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄Π΅ΠΌ ΠΎΠΆΠΈΠ΄Π°ΡΡ.
ΠΠ·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Π³Π΄Π° ΡΠ²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Ρ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ. ΠΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ pthread_cond_wait Π΄Π»Ρ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΡΡΠ»ΠΎΠ²ΠΈΡ ΠΌΡ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ Π°Π΄ΡΠ΅Ρ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ Π°Π΄ΡΠ΅Ρ ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠ³ΠΎ Ρ Π½Π΅ΠΉ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ.
ΠΡ ΠΏΡΠΎΠΈΠ»Π»ΡΡΡΡΠΈΡΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠ»ΠΎΠ²Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ , ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠ°Π² ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΠ· ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ ΡΠ°Π·Π΄Π΅Π»Π°. Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 7.5 ΠΎΠ±ΡΡΠ²Π»ΡΡΡΡΡ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Ρ ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΡΡΡΡΡ Π² ΡΡΡΡΠΊΡΡΡΡ7-13 ΠΠ²Π΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ nput ΠΈ rival Π°ΡΡΠΎΡΠΈΠΈΡΡΡΡΡΡ Ρ mutex, ΠΈ ΠΌΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΡΠ΅ΠΌ ΠΈΡ Π² ΡΡΡΡΠΊΡΡΡΡ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ put. ΠΡΠ° ΡΡΡΡΠΊΡΡΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠΌΠΈ.
14-20 ΠΡΡΠ³Π°Ρ ΡΡΡΡΠΊΡΡΡΠ°, nready, ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΠ΅ΡΡΠΈΠΊ, ΡΡΠ»ΠΎΠ²Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅. ΠΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ ΡΡΠ»ΠΎΠ²Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ PTHREAD_ COND_INITIALIZER.
Π€ΡΠ½ΠΊΡΠΈΡ main ΠΏΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Ρ Π»ΠΈΡΡΠΈΠ½Π³ΠΎΠΌ 7.3 Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΡΡΡ.
ΠΠΈΡΡΠΈΠ½Π³ 7.5. ΠΠ»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅: ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ//mutex/prodcons6.c
1 #include "unpipc.h"
2 #define MAXNITEMS 1000000
3 #define MAXNTHREADS 100
4 /* Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Π΄Π»Ρ Π²ΡΠ΅Ρ ΠΏΠΎΡΠΎΠΊΠΎΠ² */
5 int nitems; /* ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Π΅ΠΌ ΠΈ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»Π΅ΠΌ */
6 int buff[MAXNITEMS];
7 struct {
8 pthread_mutex_t mutex;
9 int nput; /* ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌΡΠΉ ΡΠ»Π΅ΠΌΠ΅Π½Ρ */
10 int nval; /* ΡΠ»Π΅Π΄ΡΡΡΠ΅Π΅ ΡΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ */
11 } put = {
12 PTHREAD_MUTEX_INITIALIZER
13 };
14 struct {
15 pthread_mutex_t mutex:
16 pthread_cond_t cond;
17 int nready; /* ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π³ΠΎΡΠΎΠ²ΡΡ Π΄Π»Ρ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ */
18 } nready = {
19 PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER
20 };
Π€ΡΠ½ΠΊΡΠΈΠΈ produce ΠΈ consume ΠΏΡΠ΅ΡΠ΅ΡΠΏΠ΅Π²Π°ΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ. ΠΡ ΡΠ΅ΠΊΡΡ Π΄Π°Π½ Π² Π»ΠΈΡΡΠΈΠ½Π³Π΅ 7.6.
ΠΠΈΡΡΠΈΠ½Π³ 7.6. Π€ΡΠ½ΠΊΡΠΈΠΈ produce ΠΈ consume//mutex/prodcons6.c
46 void *
47 produce(void *arg)
48 {
49 for (;;) {
50 Pthread_mutex_lock(&put.mutex);
51 if (put.nput >= nitems) {
52 Pthread_mutex_unlock(&put.mutex);
53 return(NULL); /* ΠΌΠ°ΡΡΠΈΠ² Π·Π°ΠΏΠΎΠ»Π½Π΅Π½, Π³ΠΎΡΠΎΠ²ΠΎ */
54 }
55 buff[put.nput] = put.nval;
56 put.nput++;
57 put.nval++;
58 Pthread_mutex_unlock(&put.mutex);
59 Pthread_mutex_lock(&nready.mutex):
60 if (nready.nready == 0)
61 Pthread_cond_signal(&nready.cond);
62 nready.nready++;
63 Pthread_mutex_unlock(&nready.mutex);
64 *((int *) arg) += 1;
65 }
66 }
67 void*
68 consume(void *arg)
69 {
70 int i;
71 for (i = 0; i < nitems; i++) {
72 Pthread_mutex_lock(&nready.mutex);
73 while (nready.nready == 0)
74 Pthread_cond_wait(&nready.cond, &nready.mutex);
75 nready.nready--;