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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сСтСвых ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 198

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

/* Π–Π΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

while (ndone == 0)

 Pthread_cond_wait(&ndone_cond, &ndone_mutex);

Но ΠΏΡ€ΠΈ этом сущСствуСт Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ послСдний ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ndone послС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π³Π»Π°Π²Π½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ условия ndone == 0, Π½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_cond_wait. Если это происходит, Ρ‚ΠΎ послСдний «сигнал» тСряСтся, ΠΈ основной Ρ†ΠΈΠΊΠ» оказываСтся Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ навсСгда, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΆΠ΄Π°Ρ‚ΡŒ события, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚.

По этой ΠΆΠ΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_cond_wait ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, послС Ρ‡Π΅Π³ΠΎ эта функция Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π² состояниС оТидания, выполняя эти дСйствия ΠΊΠ°ΠΊ ΠΎΠ΄Π½Ρƒ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ. Если Π±Ρ‹ эта функция Π½Π΅ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π»Π° Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΈ Π½Π΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π»Π° Π΅Π³ΠΎ снова послС своСго Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ эти ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ Π±Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΡƒ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ ΠΊΠΎΠ΄Π°:

/* Π–Π΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

Pthread_mutex_lock(&ndone_mutex);

while (ndone == 0) {

 Pthread_mutex_unlock(&ndone_mutex);

 Pthread_cond_wait(&ndone_cond, &ndone_mutex);

 Pthread_mutex_lock(&ndone_mutex);

}

БущСствуСт Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ выполнСния ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ndone ΠΈ это ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ pthread_mutex_unlock ΠΈ pthread_cond_wait.

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ функция pthread_cond_signal Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈΠ· состояния оТидания ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ условная пСрСмСнная. Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ ситуации, ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π½Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΈΠ· состояния оТидания Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π²Π΅Π΄Π΅Π½Ρ‹ нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ функция pthread_cond_broadcast, выводящая ΠΈΠ· состояния оТидания всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Ρ‹ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ.

#include <pthread.h>


int pthread_cond_broadcast(pthread_cond_t *cptr);

int pthread_cond_timedwait(pthread_cond_t *cptr, pthread_mutex_t *mptr,

 const struct timespec *abstime);

ОбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚: 0 Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ выполнСния, ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Exxx Π² случаС ошибки

Ѐункция pthread_cond_timedwait позволяСт ΠΏΠΎΡ‚ΠΎΠΊΡƒ Π·Π°Π΄Π°Ρ‚ΡŒ ΠΏΡ€Π΅Π΄Π΅Π»ΡŒΠ½ΠΎΠ΅ врСмя блокирования. АргумСнт abstime прСдставляСт собой структуру timespec (ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΡƒΡŽ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 6.9 ΠΏΡ€ΠΈ рассмотрСнии Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pselect), которая Π·Π°Π΄Π°Π΅Ρ‚ систСмноС врСмя для ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° функция Π΄ΠΎΠ»ΠΆΠ½Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Π΄Π°ΠΆΠ΅ Ссли ΠΊ этому ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ условная пСрСмСнная Π½Π΅ ΠΏΠΎΠ΄Π°Π»Π° сигнал. Если Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ такая ситуация, возвращаСтся ошибка ETIME.

Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ являСтся Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния Ρ€Π°Π·Π½ΠΈΡ†Ρ‹ Π²ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (time delta) ΠΌΠ΅ΠΆΠ΄Ρƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌΠΈ событиями. Π˜Π½Ρ‹ΠΌΠΈ словами, abstime β€” это систСмноС врСмя, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ количСство сСкунд ΠΈ наносСкунд, ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠΈΡ… с 1 января 1970 Π³ΠΎΠ΄Π° (UTC) Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° эта функция Π΄ΠΎΠ»ΠΆΠ½Π° Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅. Π—Π΄Π΅ΡΡŒ имССтся Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ ΠΊΠ°ΠΊ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ pselect, Ρ‚Π°ΠΊ ΠΈ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ select, Π·Π°Π΄Π°ΡŽΡ‰ΠΈΠΌΠΈ количСство сСкунд (ΠΈ наносСкунд Π² случаС pselect) Π΄ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ, ΠΊΠΎΠ³Π΄Π° функция Π΄ΠΎΠ»ΠΆΠ½Π° Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ для этого вызываСтся функция gettimeofday, которая Π²Ρ‹Π΄Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя (Π² Π²ΠΈΠ΄Π΅ структуры timeval), Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ½ΠΎ копируСтся Π² структуру timespec ΠΈ ΠΊ Π½Π΅ΠΌΡƒ добавляСтся Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅:

struct timeval tv;

struct timespec ts;


if (gettimeofday(&tv, NULL) < 0)

 err_sys("gettimeofday error");

ts.tv_sec = tv.tv_sec + 5; /* 5 с Π² Π±ΡƒΠ΄ΡƒΡ‰Π΅ΠΌ */

ts.tv_nsec = tv.tv_usec * 1000; /* микросСкунды ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΠΌ Π² наносСкунды */


pthread_cond_timedwait( , &ts);

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ использования Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ) Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ функция ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒΡΡ Ρ€Π°Π½ΡŒΡˆΠ΅ (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΈΠ·-Π·Π° ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ сигнала). Π’ΠΎΠ³Π΄Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ снова, Π½Π΅ мСняя содСрТимоС структуры timespec. НСдостаток этого способа Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² нСобходимости Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ gettimeofday ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ Π² ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π°Π· Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_cond_timedwait.

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

Π’ POSIX ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° новая функция clock_gettime, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰Π°Ρ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя Π² Π²ΠΈΠ΄Π΅ структуры timespec.

26.9. Π’Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΈ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ доступ

ИзмСним ΠΊΠΎΠ΄ нашСго Π²Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈΠ· Ρ€Π°Π·Π΄Π΅Π»Π° 26.6: ΡƒΠ±Π΅Ρ€Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Solaris thr_join ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΠΌ Π΅Π³ΠΎ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_join. Как сказано Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 26.6, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Ρ‚ΠΎΡ‡Π½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ, Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΌΡ‹ ΠΆΠ΄Π΅ΠΌ. Для этого ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΡƒΡΠ»ΠΎΠ²Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ, ΠΎΠΏΠΈΡΠ°Π½Π½ΡƒΡŽ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 26.8.

ЕдинствСнным ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π² ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠΈ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… (см. листинг 26.7) являСтся Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ Ρ„Π»Π°Π³Π° ΠΈ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ:

#define F_JOINED 8 /* количСство ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */


int ndone; /* количСство Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ²ΡˆΠΈΡ…ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t ndone_cond = PTHREAD_COND_IINITIALIZER;

ЕдинствСнным ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ do_get_read (см. листинг 26.9) Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ значСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ndone ΠΈ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅ Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π° ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ°:

 printf("end-of-file on %s\n", fptr->f_name);

 Close(fd);


 Pthread_mutex_lock(&ndone_mutex);

 fptr->f_flags = F_DONE; /* сбрасываСт Ρ„Π»Π°Π³ F_READING */

 ndone++;

 Pthread_cond_signal(&ndone_cond);

 Pthread_mutex_unlock(&ndone_mutex);


 return(fptr); /* Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ° */

}

Π‘ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ касаСтся Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π°, прСдставлСнного Π² листингС 26.8. Новая вСрсия ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π² листингС 26.13.

Листинг 26.13. Основной Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ Ρ†ΠΈΠΊΠ» Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main

//threads/web03.c

43  while (nlefttoread > 0) {

44   while (nconn < maxnconn && nlefttoconn > 0) {

45    /* Π½Π°Ρ…ΠΎΠ΄ΠΈΠΌ Ρ„Π°ΠΉΠ» для считывания */

46    for (i = 0; i < nfiles; i++)

47     if (file[i].f_flags == 0)

48      break;

49    if (i == nfiles)

50     err_quit("nlefttoconn = %d but nothing found", nlefttoconn);


51    file[i].f_flags = F_CONNECTING;

52    Pthread_create(&tid, NULL, &do_get_read, &file[i]);

53    file[i].f_tid = tid;

54    nconn++;

55    nlefttoconn--;

56   }


57   /* Π–Π΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

58   Pthread_mutex_lock(&ndone_mutex);

59   while (ndone == 0)

60    Pthread_cond_wait(&ndone_cond, &ndone_mutex);


61   for (i = 0; i < nfiles; i++) {

62    if (file[i].f_flags & F_DONE) {

63     Pthread_join(file[i].f_tid, (void**)&fptr);


64     if (&file[i] != fptr)

65      err_quit("file[i] != fptr");

66     fptr->f_flags = F_JOINED; /* clears F_DONE */

67     ndone--;

68     nconn--;

69     nlefttoread--;

70     printf("thread %d for %s done\n", fptr->f_tid, fptr->f_name);

71    }

72   }

73   Pthread_mutex_unlock(&ndone_mutex);

74  }


75  exit(0);

76 }

По возмоТности создаСм Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ

44-56 Π­Ρ‚Π° Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π° Π½Π΅ измСнилась.

Π–Π΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ°

57-60 ΠœΡ‹ ΠΆΠ΄Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², отслСТивая, ΠΊΠΎΠ³Π΄Π° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ndone станСт Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ. Как сказано Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 26.8, эта ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅Π½Π° ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΎ, Π° ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π² состояниС оТидания осущСствляСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ pthread_cond_wait.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°

61-73 ΠšΠΎΠ³Π΄Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΠΎΡΡŒ, ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π±ΠΈΡ€Π°Π΅ΠΌ всС структуры file, отыскивая ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ pthread_join, Π° Π·Π°Ρ‚Π΅ΠΌ устанавливаСм Π½ΠΎΠ²Ρ‹ΠΉ Ρ„Π»Π°Π³ F_JOINED.

Π’ Ρ‚Π°Π±Π». 16.1 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, сколько Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ этой вСрсии Π²Π΅Π±-ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ вСрсии, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΉ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ connect.

26.10. РСзюмС

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ мСньшС Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Ρ‡Π΅ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ процСсса с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fork. Одно это ΡƒΠΆΠ΅ являСтся большим прСимущСством использования ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π½Π° Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΡ… сСтСвых сСрвСрах. ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, ΠΎΠ΄Π½Π°ΠΊΠΎ, прСдставляСт собой ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡŽ, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΡƒΡŽ большСй аккуратности ΠΏΡ€ΠΈ использовании.

ВсС ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ дСскрипторы, Ρ‚Π΅ΠΌ самым эта информация становится доступной всСм ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ процСсса. Но совмСстноС использованиС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ вносит ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, связанныС с синхронизациСй доступа ΠΊ раздСляСмым ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ, ΠΈ поэтому Π½Π°ΠΌ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ синхронизации Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Pthreads β€” Π²Π·Π°ΠΈΠΌΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ условныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅. Бинхронизация доступа ΠΊ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ Π΄Π°Π½Π½Ρ‹ΠΌ β€” Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ условиС ΠΏΠΎΡ‡Ρ‚ΠΈ для любого прилоТСния, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ.