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

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

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

72 Π€ΡƒΠ½ΠΊΡ†ΠΈΡ write_get_cmd Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ HTTP GET ΠΈ отсылаСт Π΅Π΅ сСрвСру. ΠœΡ‹ Π½Π΅ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π·Π°Π½ΠΎΠ²ΠΎ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ СдинствСнным ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ΠΌ ΠΎΡ‚ листинга 16.12 являСтся Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² вСрсии, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π΅ΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π½Π΅ вызываСтся макрос FD_SET ΠΈ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ maxfd.

Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΎΡ‚Π²Π΅Ρ‚Π° сСрвСра

73-82 Π—Π°Ρ‚Π΅ΠΌ считываСтся ΠΎΡ‚Π²Π΅Ρ‚ сСрвСра. Когда соСдинСниС закрываСтся сСрвСром, устанавливаСтся Ρ„Π»Π°Π³ F_DONE ΠΈ функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ home_page, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½Π° ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ повторяСт Π²Π΅Ρ€ΡΠΈΡŽ, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΡƒΡŽ Π² листингС 16.10.

ΠœΡ‹ вСрнСмся ΠΊ этому ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Π·Π°ΠΌΠ΅Π½ΠΈΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Solaris thr_join Π½Π° Π±ΠΎΠ»Π΅Π΅ ΠΏΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ сСмСйства Pthreads, Π½ΠΎ сначала Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±ΡΡƒΠ΄ΠΈΡ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ условныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅.

26.7. Π’Π·Π°ΠΈΠΌΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² листингС 26.8 ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ выполнСния ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π² Π³Π»Π°Π²Π½ΠΎΠΌ Ρ†ΠΈΠΊΠ»Π΅ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°ΡŽΡ‚ΡΡ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ ΠΈ nconn, ΠΈ nlefttoread. ΠœΡ‹ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ‹ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΎΠ±Π° эти ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡ Π² ΠΎΠ΄Π½Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ do_get_read, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΠ»ΠΎ Π±Ρ‹ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Ρ‚ΡŒ эти счСтчики нСпосрСдствСнно ΠΏΠ΅Ρ€Π΅Π΄ Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. Но это ΠΏΡ€ΠΈΠ²Π΅Π»ΠΎ Π±Ρ‹ ΠΊ возникновСнию Ρ‚Ρ€ΡƒΠ΄Π½ΠΎΡƒΠ»ΠΎΠ²ΠΈΠΌΠΎΠΉ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΠΎΠΉ ошибки ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования.

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

1. Π’ыполняСтся ΠΏΠΎΡ‚ΠΎΠΊ А, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ Π² рСгистр Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ nconn (Ρ€Π°Π²Π½ΠΎΠ΅ 3).

2. Π‘истСма ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ с выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ° А Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π’. РСгистры ΠΏΠΎΡ‚ΠΎΠΊΠ° А сохранСны, рСгистры ΠΏΠΎΡ‚ΠΎΠΊΠ° Π’ восстановлСны.

3. ΠŸΠΎΡ‚ΠΎΠΊ Π’ выполняСт Ρ‚Ρ€ΠΈ дСйствия, ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° Π² языкС Π‘ (nconn--), сохраняя Π½ΠΎΠ²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ nconn, Ρ€Π°Π²Π½ΠΎΠ΅ 2.

4. Π’послСдствии Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ систСма ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° А. Π’ΠΎΡΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ рСгистры ΠΏΠΎΡ‚ΠΎΠΊΠ° А, ΠΈ ΠΎΠ½ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ с Ρ‚ΠΎΠ³ΠΎ мСста, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ остановился, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ начиная со Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ этапа ΠΈΠ· Ρ‚Ρ€Π΅Ρ…, ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π°. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ рСгистра ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ΡΡ с 3 Π΄ΠΎ 2, ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 2 записываСтся Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ nconn.

ΠžΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ‚Π°ΠΊΠΎΠ²: Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ nconn Ρ€Π°Π²Π½ΠΎ 2, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π½Ρ‹ΠΌ 1. Π­Ρ‚ΠΎ ошибка.

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

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ с использованиСм ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² являСтся ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Ρ‹ΠΌ (parallel), ΠΈΠ»ΠΈ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ (concurrent), ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ (ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ), получая доступ ΠΊ ΠΎΠ΄Π½ΠΈΠΌ ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ. Π₯отя ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½Ρ‹ΠΉ сцСнарий, рассмотрСнный Π½Π°ΠΌΠΈ Π΄Π°Π»Π΅Π΅, ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ систСму с ΠΎΠ΄Π½ΠΈΠΌ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½Ρ‹ΠΌ процСссором, Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ ошибки Ρ‚Π°ΠΊΠΆΠ΅ присутствуСт, Ссли ΠΏΠΎΡ‚ΠΎΠΊΠΈ А ΠΈ Π’ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ΄Π½ΠΎ ΠΈ Ρ‚ΠΎ ΠΆΠ΅ врСмя Π½Π° Ρ€Π°Π·Π½Ρ‹Ρ… процСссорах Π² многопроцСссорной систСмС. Π’ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΏΠΎΠ΄ Unix ΠΌΡ‹ Π½Π΅ сталкиваСмся с ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌΠΈ ошибками, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΡ€ΠΈ использовании Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fork Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΈ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСссы Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ совмСстно Π½ΠΈΡ‡Π΅Π³ΠΎ, ΠΊΡ€ΠΎΠΌΠ΅ дСскрипторов. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΠΌΡ‹ столкнСмся с ошибками этого Ρ‚ΠΈΠΏΠ° ΠΏΡ€ΠΈ обсуТдСнии совмСстного использовании памяти нСсколькими процСссами.

Π­Ρ‚Ρƒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ с Π»Π΅Π³ΠΊΠΎΡΡ‚ΡŒΡŽ ΠΏΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π’ листингС 26.11 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая создаСт Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, послС Ρ‡Π΅Π³ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ 5000 Ρ€Π°Π·.

ΠœΡ‹ повысили Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ ошибки Π·Π° счСт Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Π»ΠΈ ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ counter, вывСсти это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π΅Π³ΠΎ. Если ΠΌΡ‹ запустим эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚, прСдставлСнный Π² листингС 26.10.

Листинг 26.10. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΉ Π² листингС 26.11

4: 1

4: 2

4: 3

4: 4

 ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½ΠΎΠΌΠ΅Ρ€ 4

4: 517

4: 518

5: 518 Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ выполняСтся ΠΏΠΎΡ‚ΠΎΠΊ Π½ΠΎΠΌΠ΅Ρ€ 5

5: 519

5: 520

 ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½ΠΎΠΌΠ΅Ρ€ 5

5: 926

5: 927

4: 519 Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ выполняСтся ΠΏΠΎΡ‚ΠΎΠΊ Π½ΠΎΠΌΠ΅Ρ€ 4, записывая Π½Π΅Π²Π΅Ρ€Π½Ρ‹Π΅ значСния

4: 520

Листинг 26.11. Π”Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅Π²Π΅Ρ€Π½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ глобальной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ

//threads/example01.c

 1 #include "unpthread.h"


 2 #define NLOOP 5000


 3 int counter; /* ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этой ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ */


 4 void *doit(void*);


 5 int

 6 main(int argc, char **argv)

 7 {

 8  pthread_t tidA, tidB;


 9  Pthread_create(&tidA, NULL, &doit, NULL);

10  Pthread_create(&tidB, NULL, &doit, NULL);


11  /* ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠ±ΠΎΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

12  Pthread_join(tidA, NULL);

13  Pthread_join(tidB, NULL);


14  exit(0);

15 }


16 void*

17 doit(void *vptr)

18 {

19  int i, val;


20  /* ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚, Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π½Π°

21   * Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ counter NLOOP Ρ€Π°Π·. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅

22   * ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Ρ‚ΡŒΡΡ ΠΌΠΎΠ½ΠΎΡ‚ΠΎΠ½Π½ΠΎ.

23   */


24  for (i = 0; i < NLOOP; i++) {

25   val = counter;

26   printf("%d: %d\n", pthread_self(), val + 1);

27   counter = val + 1;

28  }


29  return (NULL);

30 }

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π°Π· ошибка происходит ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ систСмы с выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½ΠΎΠΌΠ΅Ρ€ 4 Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½ΠΎΠΌΠ΅Ρ€ 5: ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π² ΠΈΡ‚ΠΎΠ³Π΅ записываСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 518. Π­Ρ‚ΠΎ происходит мноТСство Ρ€Π°Π· Π½Π° протяТСнии 10 000 строк Π²Ρ‹Π²ΠΎΠ΄Π°.

НСдСтСрминированная ΠΏΡ€ΠΈΡ€ΠΎΠ΄Π° ошибок Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Π°, Ссли ΠΌΡ‹ запустим ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ нСсколько Ρ€Π°Π·: ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ. Π’Π°ΠΊΠΆΠ΅, Ссли ΠΌΡ‹ пСрСадрСсуСм Π²Ρ‹Π²ΠΎΠ΄ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² Π² Ρ„Π°ΠΉΠ» Π½Π° дискС, эта ошибка ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Ρ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° станСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ быстрСС, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΡŽ вСроятности ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ систСмы ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. НаибольшСС количСство ошибок Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ Π² случаС, Ссли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ, записывая Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π½Π° ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΉ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π», Π½ΠΎ ΠΏΡ€ΠΈ этом Ρ‚Π°ΠΊΠΆΠ΅ сохраняя Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π² Ρ„Π°ΠΉΠ» ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Unix script (которая описана Π² Π³Π»Π°Π²Π΅ 19 ΠΊΠ½ΠΈΠ³ΠΈ [110]).

Волько Ρ‡Ρ‚ΠΎ описанная ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π°Ρ, ΠΊΠΎΠ³Π΄Π° нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈΠ·ΠΌΠ΅Π½ΡΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, являСтся самой простой ΠΈΠ· ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования. Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ Π²Π·Π°ΠΈΠΌΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (mutex β€” mutual exclusion), с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… контролируСтся доступ ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. Π’ Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Ρ… Pthreads Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ β€” это пСрСмСнная Ρ‚ΠΈΠΏΠ° pthread_mutex_t, которая ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π° ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π΄Π²ΡƒΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ:

#include <pthread.h>


int pthread_mutex_lock(pthread_mutex_t *mptr);

int pthread_mutex_unlock(pthread_mutex_t *mptr);

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

Если Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ попытаСтся Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΆΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΎ ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ‚ Π΅ΠΌΡƒ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ), этот ΠΏΠΎΡ‚ΠΎΠΊ окаТСтся Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π΄ΠΎ освобоТдСния Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ.

Если пСрСмСнная-ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π° Π² памяти статичСски, слСдуСт ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π΅ константой PTHREAD_MUTEX_INITIALIZER. Π’ Ρ€Π°Π·Π΄Π΅Π»Π΅ 30.8 ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ссли ΠΌΡ‹ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅ΠΌ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ (раздСляСмой) памяти, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π²ΠΎ врСмя выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΡƒΡ‚Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_mutex_init.