ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΈΡΡΠ΅ΠΌΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Solaris) ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΡ PTHREAD_MUTEX_INITIALIZER ΠΊΠ°ΠΊ 0. ΠΡΠ»ΠΈ Π΄Π°Π½Π½Π°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π±ΡΠ΄Π΅Ρ ΠΎΠΏΡΡΠ΅Π½Π°, ΡΡΠΎ Π½ΠΈ Π½Π° ΡΡΠΎ Π½Π΅ ΠΏΠΎΠ²Π»ΠΈΡΠ΅Ρ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ°Π·ΠΌΠ΅ΡΠ°Π΅ΠΌΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΡΡΡΡ Π½ΡΠ»Π΅ΠΌ. ΠΠΎ Π΄Π»Ρ Π΄ΡΡΠ³ΠΈΡ ΡΠΈΡΡΠ΅ΠΌ ΡΠ°ΠΊΠΎΠΉ Π³Π°ΡΠ°Π½ΡΠΈΠΈ Π΄Π°ΡΡ Π½Π΅Π»ΡΠ·Ρ β Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Digital Unix ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ° ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π΅Π½ΡΠ»Π΅Π²Π°Ρ.
Π Π»ΠΈΡΡΠΈΠ½Π³Π΅ 26.12 ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ Π»ΠΈΡΡΠΈΠ½Π³Π° 26.11, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΎΠ΄Π½ΠΎ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ΅ΡΡΠΈΠΊΠ° ΠΏΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Ρ Π΄Π²ΡΠΌΡ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ.
ΠΠΈΡΡΠΈΠ½Π³ 26.12. ΠΡΠΏΡΠ°Π²Π»Π΅Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ Π»ΠΈΡΡΠΈΠ½Π³Π° 26.11, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ°Ρ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Π·Π°ΡΠΈΡΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ
//threads/examplΠ΅01.Ρ
1 #include "unpthread.h"
2 #define NLOOP 5000
3 int counter; /* ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ */
4 pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
5 void *doit(void*);
6 int
7 main(int argc, char **argv)
8 {
9 pthread_t tidA, tidB;
10 Pthread_create(&tidA, NULL, &doit, NULL);
11 Pthread_create(&tidB, NULL, &doit, NULL);
12 /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ ΠΎΠ±ΠΎΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² */
13 Pthread_join(tidA, NULL);
14 Pthread_join(tidB, NULL);
15 exit(0);
16 }
17 void*
18 doit(void *vptr)
19 {
20 int i, val;
21 /*
22 * ΠΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΡΠΎΠΊ ΡΡΠΈΡΡΠ²Π°Π΅Ρ, Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΠΈ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅Ρ ΡΡΠ΅ΡΡΠΈΠΊ NLOOP ΡΠ°Π·.
23 * ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π²ΠΎΠ·ΡΠ°ΡΡΠ°ΡΡ ΠΌΠΎΠ½ΠΎΡΠΎΠ½Π½ΠΎ.
24 */
25 for (i = 0; i < NLOOP; i++) {
26 Pthread_mutex_lock(&counter_mutex);
27 val = counter;
28 printf(%d: %d\n", pthread_self(), val + 1);
29 counter = val + 1;
30 Pthread_mutex_unlock(&counter_mutex);
31 }
32 return(NULL);
33 }
ΠΡ ΠΎΠ±ΡΡΠ²Π»ΡΠ΅ΠΌ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ counter_mutex. ΠΡΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠΌ Π½Π° ΡΠΎ Π²ΡΠ΅ΠΌΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΡΠ΅Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ counter. ΠΠΎΠ³Π΄Π° ΠΌΡ Π·Π°ΠΏΡΡΠΊΠ°Π»ΠΈ ΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π²ΡΠ΅Π³Π΄Π° Π±ΡΠ» ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΡΠΌ: Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π»ΠΎΡΡ ΠΌΠΎΠ½ΠΎΡΠΎΠ½Π½ΠΎ, Π° Π΅Π΅ ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Π³Π΄Π° ΠΎΠΊΠ°Π·ΡΠ²Π°Π»ΠΎΡΡ ΡΠ°Π²Π½ΡΠΌ 10 000.
ΠΠ°ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ΅ΡΡΠ΅Π·Π½ΠΎΠΉ ΡΠ²Π»ΡΠ΅ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½Π°Ρ Π½Π°Π³ΡΡΠ·ΠΊΠ°, ΡΠ²ΡΠ·Π°Π½Π½Π°Ρ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π²Π·Π°ΠΈΠΌΠ½ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ? ΠΡ ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ»ΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠ΅ Π² Π»ΠΈΡΡΠΈΠ½Π³Π°Ρ 26.11 ΠΈ 26.12, Π·Π°ΠΌΠ΅Π½ΠΈΠ² Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ NLOOP Π½Π° 50 000 (Π²ΠΌΠ΅ΡΡΠΎ ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ 5000), ΠΈ Π·Π°ΡΠ΅ΠΊΠ»ΠΈ Π²ΡΠ΅ΠΌΡ, Π½Π°ΠΏΡΠ°Π²ΠΈΠ² Π²ΡΠ²ΠΎΠ΄ Π½Π° ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ /dev/null. ΠΡΠ΅ΠΌΡ ΡΠ°Π±ΠΎΡΡ ΡΠ΅Π½ΡΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ° Π² ΡΠ»ΡΡΠ°Π΅ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠ΅ΠΉ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΡΠ²Π΅Π»ΠΈΡΠΈΠ»ΠΎΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΡΠ°Π±ΠΎΡΡ Π½Π΅ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ Π±Π΅Π· Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π½Π° 10 %. ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π½Π΅ ΡΠ²ΡΠ·Π°Π½ΠΎ ΡΠΎ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΠΈΠ·Π΄Π΅ΡΠΆΠΊΠ°ΠΌΠΈ.
26.8. Π£ΡΠ»ΠΎΠ²Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅
ΠΠ·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠΉ (ΡΠ°Π·Π΄Π΅Π»ΡΠ΅ΠΌΠΎΠΉ) ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π½ΠΎ Π΄Π»Ρ ΡΠΎΠ³ΠΎ ΡΡΠΎΠ±Ρ ΠΏΠ΅ΡΠ΅Π²Π΅ΡΡΠΈ ΠΏΠΎΡΠΎΠΊ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ (ΡΠΏΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅) Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΡΡΠ»ΠΎΠ²ΠΈΡ, Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌ Π΄ΡΡΠ³ΠΎΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ. ΠΡΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅ΠΌ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π½Π° ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅. ΠΠ΅ΡΠ½Π΅ΠΌΡΡ ΠΊ Π½Π°ΡΠ΅ΠΌΡ Π²Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½ΡΡ ΠΈΠ· ΡΠ°Π·Π΄Π΅Π»Π° 26.6 ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΠΌ ΡΡΠ½ΠΊΡΠΈΡ Solaris thr_join Π½Π° pthread_join. ΠΠΎ ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΡΠ·Π²Π°ΡΡ ΡΡΠ½ΠΊΡΠΈΡ pthread_join Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡΠ΄Π΅ΠΌ Π·Π½Π°ΡΡ, ΡΡΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠ° Π·Π°Π²Π΅ΡΡΠΈΠ»ΠΎΡΡ. Π‘Π½Π°ΡΠ°Π»Π° ΠΌΡ ΠΎΠ±ΡΡΠ²Π»ΡΠ΅ΠΌ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ»ΡΠΆΠΈΡ ΡΡΠ΅ΡΡΠΈΠΊΠΎΠΌ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° Π·Π°Π²Π΅ΡΡΠΈΠ²ΡΠΈΡ ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ², ΠΈ ΠΎΡΠ³Π°Π½ΠΈΠ·ΡΠ΅ΠΌ ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠΎΠΌ ΠΊ Π½Π΅ΠΉ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ.
int ndone; /* ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ², Π·Π°Π²Π΅ΡΡΠΈΠ²ΡΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ */
pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;
ΠΠ°ΡΠ΅ΠΌ ΠΌΡ ΡΡΠ΅Π±ΡΠ΅ΠΌ, ΡΡΠΎΠ±Ρ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΡΠΎΠΊ ΠΏΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ ΡΠ²ΠΎΠ΅Π³ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π» ΡΡΠΎΡ ΡΡΠ΅ΡΡΠΈΠΊ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π΅ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅.
void* do_get_read(void *vptr) {
...
Pthread_mutex_lock(&ndone_mutex);
ndone++;
Pthread_mutex_unlock(&ndone_mutex);
return(fptr); /* Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠ° */
}
ΠΠΎ ΠΊΠ°ΠΊΠΈΠΌ ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΏΠΎΠ»ΡΡΠ°Π΅ΡΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΈΠΊΠ»? ΠΠ·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡΡΡ ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΎ ΠΎΡΠ½ΠΎΠ²Π½ΡΠΌ ΡΠΈΠΊΠ»ΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ Π·Π°Π²Π΅ΡΡΠΈΠ»ΠΈ ΡΠ²ΠΎΠ΅ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅.
while (nlefttoread > 0) {
while (nconn < maxnconn && nlefttoconn > 0) {
/* Π½Π°Ρ ΠΎΠ΄ΠΈΠΌ ΡΠ°ΠΉΠ» Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ */
...
}
/* ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ, Π½Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ Π»ΠΈ ΠΏΠΎΡΠΎΠΊ */
Pthread_mutex_lock(&ndone_mutex);
if (ndone > 0) {
for (i =0; i < nfiles; i++) {
if (file[i].f_flags & F_DONE) {
Pthread_join(file[i].f_tid, (void**)&fptr);
/* ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌ file[i] Π΄Π»Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° */
...
}
}
}
Pthread_mutex_unlock(&ndone_mutex);
}
ΠΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π³Π»Π°Π²Π½ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΡ Π² ΡΠΏΡΡΠ΅Π΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅, Π° ΠΏΡΠΎΡΡΠΎ Π²Ρ ΠΎΠ΄ΠΈΡ Π² ΡΠΈΠΊΠ», ΠΏΡΠΎΠ²Π΅ΡΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ndone. ΠΡΠΎΡ ΠΏΡΠΎΡΠ΅ΡΡ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ ΠΎΠΏΡΠΎΡΠΎΠΌ (polling) ΠΈ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π΅ΡΡΡ ΠΊΠ°ΠΊ ΠΏΡΡΡΠ°Ρ ΡΡΠ°ΡΠ° Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΡΠ΅Π½ΡΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°.
ΠΠ°ΠΌ Π½ΡΠΆΠ΅Π½ ΠΌΠ΅ΡΠΎΠ΄, Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π³Π»Π°Π²Π½ΡΠΉ ΡΠΈΠΊΠ» ΠΌΠΎΠ³ Π±Ρ Π²Ρ ΠΎΠ΄ΠΈΡΡ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ, ΠΏΠΎΠΊΠ° ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ² Π½Π΅ ΠΎΠΏΠΎΠ²Π΅ΡΡΠΈΡ Π΅Π³ΠΎ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ ΠΊΠ°ΠΊΠ°Ρ-Π»ΠΈΠ±ΠΎ Π·Π°Π΄Π°ΡΠ° Π²ΡΠΏΠΎΠ»Π½Π΅Π½Π°. ΠΡΠ° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ (conditional variable) Π²ΠΌΠ΅ΡΡΠ΅ ΡΠΎ Π²Π·Π°ΠΈΠΌΠ½ΡΠΌ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ. ΠΠ·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π° ΡΡΠ»ΠΎΠ²Π½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ ΡΠΈΠ³Π½Π°Π»ΡΠ½ΡΠΉ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌ.
Π ΡΠ΅ΡΠΌΠΈΠ½Π°Ρ Pthreads ΡΡΠ»ΠΎΠ²Π½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ β ΡΡΠΎ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠΈΠΏΠ° pthread_cond_t. Π’Π°ΠΊΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π² ΡΠ»Π΅Π΄ΡΡΡΠΈΡ Π΄Π²ΡΡ ΡΡΠ½ΠΊΡΠΈΡΡ :
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
int pthread_cond_signal(pthread_cond_t *cptr);
ΠΠ±Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ: 0 Π² ΡΠ»ΡΡΠ°Π΅ ΡΡΠΏΠ΅ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ, ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Exxx Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ
Π‘Π»ΠΎΠ²ΠΎ signal Π² Π½Π°Π·Π²Π°Π½ΠΈΠΈ Π²ΡΠΎΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΡ ΠΊ ΡΠΈΠ³Π½Π°Π»Π°ΠΌ Unix SIGxxx.
ΠΡΠΎΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΎΠ±ΡΡΡΠ½ΠΈΡΡ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ ΡΡΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΉ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅. ΠΠ΅ΡΠ½Π΅ΠΌΡΡ ΠΊ Π½Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠΌΠ΅ΡΡ Π²Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½ΡΠ°. Π‘ΡΠ΅ΡΡΠΈΠΊ ndone ΡΠ΅ΠΏΠ΅ΡΡ Π°ΡΡΠΎΡΠΈΠΈΡΡΠ΅ΡΡΡ ΠΈ Ρ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΈ Ρ Π²Π·Π°ΠΈΠΌΠ½ΡΠΌ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ:
int ndone;
pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;
ΠΠΎΡΠΎΠΊ ΠΎΠΏΠΎΠ²Π΅ΡΠ°Π΅Ρ Π³Π»Π°Π²Π½ΡΠΉ ΡΠΈΠΊΠ» ΠΎ ΡΠ²ΠΎΠ΅ΠΌ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ, ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅ΡΡΠΈΠΊΠ°, ΠΏΠΎΠΊΠ° Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ Π΄Π°Π½Π½ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ (Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½ΠΎ ΠΈΠΌ), ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΡΠ»ΠΎΠ²Π½ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ Π΄Π»Ρ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ.
Pthread_mutex_lock(&ndone_mutex);
ndone++;
Pthread_cond_signal(&ndone_cond);
Pthread_mutex_unlock(&ndone_mutex);
ΠΠ°ΡΠ΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΈΠΊΠ» Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π² Π²ΡΠ·ΠΎΠ²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ pthread_cond_wait, ΠΎΠΆΠΈΠ΄Π°Ρ ΠΎΠΏΠΎΠ²Π΅ΡΠ΅Π½ΠΈΡ ΠΎ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΏΠΎΡΠΎΠΊΠ°:
while (nlefttoread > 0) {
while (nconn < maxnconn && nlefttoconn > 0) {
/* Π½Π°Ρ ΠΎΠ΄ΠΈΠΌ ΡΠ°ΠΉΠ» Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ */
...
}
/* ΠΠ΄Π΅ΠΌ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΠΏΠΎΡΠΎΠΊΠ° */
Pthread_mutex_lock(&ndone_mutex);
while (ndone == 0)
Pthread_cond_wait(&ndone_cond, &ndone_mutex);
for (i = 0; i < nfiles; i++) {
if (file[i].f_flags & F_DONE) {
Pthread_join(file[i].f_tid, (void**)&fptr);
/* ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌ file[i] Π΄Π»Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° */
...
}
}
Pthread_mutex_unlock(&ndone_mutex);
}
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΠΎ, ΡΡΠΎ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ndone ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ, ΡΠΎΠ»ΡΠΊΠΎ Π΅ΡΠ»ΠΈ ΠΏΠΎΡΠΎΠΊΡ ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅. Π’ΠΎΠ³Π΄Π°, Π΅ΡΠ»ΠΈ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΠ΅, Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΡΠ½ΠΊΡΠΈΡ pthread_cond_wait. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π²ΡΠ·ΡΠ²Π°ΡΡΠΈΠΉ ΠΏΠΎΡΠΎΠΊ ΠΏΠ΅ΡΠ΅Ρ ΠΎΠ΄ΠΈΡ Π² ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ, ΠΈ ΡΠ°Π·Π±Π»ΠΎΠΊΠΈΡΡΠ΅ΡΡΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Π»ΠΎ ΡΡΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, ΠΊΠΎΠ³Π΄Π° ΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΡΡ ΠΏΠΎΡΠΎΠΊΡ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ pthread_cond_wait (ΠΏΠΎΡΠ»Π΅ ΡΠΎΠ³ΠΎ ΠΊΠ°ΠΊ ΠΏΠΎΡΡΡΠΏΠΈΠ» ΡΠΈΠ³Π½Π°Π» ΠΎΡ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°), ΠΎΠ½ ΡΠ½ΠΎΠ²Π° Π±Π»ΠΎΠΊΠΈΡΡΠ΅Ρ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅.
ΠΠΎΡΠ΅ΠΌΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ΅Π³Π΄Π° ΡΠ²ΡΠ·Π°Π½ΠΎ Ρ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ? Β«Π£ΡΠ»ΠΎΠ²ΠΈΠ΅Β» ΠΎΠ±ΡΡΠ½ΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠ±ΠΎΠΉ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠΉ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ. ΠΠ·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ ΠΌΠΎΠ³Π»ΠΈ Π·Π°Π΄Π°Π²Π°ΡΡ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΡΠ»ΠΎΠ²Π½ΠΎΠΉ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΊΠΎΠ΄Π°, ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ ΡΠ°Π½Π΅Π΅, ΠΎΡΡΡΡΡΡΠ²ΠΎΠ²Π°Π»ΠΎ Π±Ρ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅, ΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° Π² Π³Π»Π°Π²Π½ΠΎΠΌ ΡΠΈΠΊΠ»Π΅ Π²ΡΠ³Π»ΡΠ΄Π΅Π»Π° Π±Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
/* ΠΠ΄Π΅ΠΌ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² */
while (ndone == 0)
Pthread_cond_wait(&ndone_cond, &ndone_mutex);
ΠΠΎ ΠΏΡΠΈ ΡΡΠΎΠΌ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π²Π΅ΡΠΎΡΡΠ½ΠΎΡΡΡ, ΡΡΠΎ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΏΠΎΡΠΎΠΊ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ndone ΠΏΠΎΡΠ»Π΅ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π³Π»Π°Π²Π½ΡΠΌ ΠΏΠΎΡΠΎΠΊΠΎΠΌ ΡΡΠ»ΠΎΠ²ΠΈΡ ndone == 0, Π½ΠΎ ΠΏΠ΅ΡΠ΅Π΄ Π²ΡΠ·ΠΎΠ²ΠΎΠΌ ΡΡΠ½ΠΊΡΠΈΠΈ pthread_cond_wait. ΠΡΠ»ΠΈ ΡΡΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ, ΡΠΎ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ Β«ΡΠΈΠ³Π½Π°Π»Β» ΡΠ΅ΡΡΠ΅ΡΡΡ, ΠΈ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΈΠΊΠ» ΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ Π·Π°Π±Π»ΠΎΠΊΠΈΡΠΎΠ²Π°Π½Π½ΡΠΌ Π½Π°Π²ΡΠ΅Π³Π΄Π°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΠΆΠ΄Π°ΡΡ ΡΠΎΠ±ΡΡΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΡΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ.