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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для Linux. ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 17

Автор ΠœΠ°Ρ€ΠΊ ΠœΠΈΡ‚Ρ‡Π΅Π»Π»

Π‘ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния ΠΏΠΎΡ‚ΠΎΠΊ сущСствуСт Π²Π½ΡƒΡ‚Ρ€ΠΈ процСсса, являясь Π±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π»ΠΊΠΎΠΉ Π΅Π΄ΠΈΠ½ΠΈΡ†Π΅ΠΉ управлСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ. ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Linux создаСт для Π½Π΅Π΅ Π½ΠΎΠ²Ρ‹ΠΉ процСсс, Π° Π² Π½Π΅ΠΌ β€” СдинствСнный ΠΏΠΎΡ‚ΠΎΠΊ, ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄. Π­Ρ‚ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ. ВсС ΠΎΠ½ΠΈ находятся Π² ΠΎΠ΄Π½ΠΎΠΌ процСссС, выполняя Ρ‚Ρƒ ΠΆΠ΅ ΡΠ°ΠΌΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Π½ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π² Ρ€Π°Π·Π½Ρ‹Ρ… Π΅Π΅ мСстах.

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

Π’ Linux Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° API-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ стандарту POSIX (ΠΎΠ½Π° называСтся Pthreads). ВсС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Ρ‚ΠΈΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ Π² Ρ„Π°ΠΉΠ»Π΅ <pthread.h>. Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ входят Π² ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ языка Π‘, поэтому ΠΏΡ€ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠΏΡ†ΠΈΡŽ -lpthread Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкС.

4.1. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°

ΠšΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ Π² процСссС назначаСтся собствСнный ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€. ΠŸΡ€ΠΈ ссылкС Π½Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…, написанных Π½Π° языкС Π‘ ΠΈΠ»ΠΈ C++, Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… pthread_t.

ПослС создания ΠΏΠΎΡ‚ΠΎΠΊ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Π­Ρ‚ΠΎ самая обычная функция, которая содСрТит ΠΊΠΎΠ΄ ΠΏΠΎΡ‚ΠΎΠΊΠ°. По Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΡ‚ΠΎΠΊ уничтоТаСтся. Π’ Linux ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ СдинствСнный ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° void* ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π­Ρ‚ΠΎΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ называСтся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π§Π΅Ρ€Π΅Π· Π½Π΅Π³ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. Аналогичным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρ‡Π΅Ρ€Π΅Π· Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

Ѐункция pthread_create() создаСт Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. Π•ΠΉ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹.

β–  Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ‚ΠΈΠΏΠ° pthread_t, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ сохраняСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

β–  Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π­Ρ‚ΠΎΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ опрСдСляСт взаимодСйствиС ΠΏΠΎΡ‚ΠΎΠΊΠ° с ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ Ρ‡Π°ΡΡ‚ΡŒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Если Π·Π°Π΄Π°Ρ‚ΡŒ Π΅Π³ΠΎ Ρ€Π°Π²Π½Ρ‹ΠΌ NULL, ΠΏΠΎΡ‚ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ создан со стандартными Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ данная Ρ‚Π΅ΠΌΠ° обсуТдаСтся Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 4.1.5, "Атрибуты ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²".

β–  Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Ѐункция ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ‚ΠΈΠΏ:

void* (*)(void*)

β–  Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° (Ρ‚ΠΈΠΏ void*). Π”Π°Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ пСрСдаСтся ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Ѐункция pthread_create() Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, ΠΈ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ инструкции, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ послС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π’Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. ОБ Linux ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΎΠ±ΠΎΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² асинхронно, поэтому ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Π° Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° ΠΊΠ°ΠΊΡƒΡŽ-Ρ‚ΠΎ ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, прСдставлСнная Π² листингС 4.1, создаСт ΠΏΠΎΡ‚ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎ записываСт символы 'x' Π² стандартный ΠΏΠΎΡ‚ΠΎΠΊ ошибок. ПослС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_create() основной ΠΏΠΎΡ‚ΠΎΠΊ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚ΠΎ ΠΆΠ΅ самоС, Π½ΠΎ вмСсто символов 'x' ΠΏΠ΅Ρ‡Π°Ρ‚Π°ΡŽΡ‚ΡΡ символы 'o'.

Листинг 4.1. (thread-create.c) Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°

#include <pthread.h>

#include <stdio.h>


/* Π—Π°ΠΏΠΈΡΡŒ символов 'x' Π² ΠΏΠΎΡ‚ΠΎΠΊ stderr.

   ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ.

   Ѐункция Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ. */


void* print_xs(void* unseed) {

 while (1)

  fputc('x', stderr);

 return NULL;

}


/* Основная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°. */

int main() {

 pthread_t thread_id;

 /* Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Новый ΠΏΠΎΡ‚ΠΎΠΊ выполняСт

    Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ print_xs(). */

 pthread_create(&thread_id, NULL, &print_xs, NULL);

 /* НСпрСрывная запись символов 'o' Π² ΠΏΠΎΡ‚ΠΎΠΊ stderr. */

 while (1)

  fputc('o', stderr);

 return 0;

}

ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡ ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡŽΡ‚ΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

% cc -o thread-create thread-create.c -lpthread

ЗапуститС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΈ Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ символы 'x' ΠΈ 'o' Ρ‡Π΅Ρ€Π΅Π΄ΡƒΡŽΡ‚ΡΡ самым нСпрСдсказуСмым ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

ΠŸΡ€ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°Ρ… ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Π΄Π²ΡƒΡ… способов. Один ΠΈΠ· Π½ΠΈΡ… β€” Π²Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Сю Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ считаСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΌ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ° Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Π’Ρ‚ΠΎΡ€ΠΎΠΉ способ— Π²Ρ‹Π·ΠΎΠ² ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_exit(). Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ сдСлано ΠΊΠ°ΠΊ Π² ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚Π°ΠΊ ΠΈ Π² любой Π΄Ρ€ΡƒΠ³ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, явно ΠΈΠ»ΠΈ нСявно Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ ΠΈΠ· Π½Π΅Π΅. АргумСнт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_exit() являСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ возвращаСтся ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ.

4.1.1. ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΡƒ

ΠŸΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это ΡƒΠ΄ΠΎΠ±Π½ΠΎΠ΅ срСдство ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. Но ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π΅Π³ΠΎ Ρ‚ΠΈΠΏ void*, Π΄Π°Π½Π½Ρ‹Π΅ содСрТатся Π½Π΅ Π² самом Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π΅. Он лишь Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° ΠΊΠ°ΠΊΡƒΡŽ-Ρ‚ΠΎ структуру ΠΈΠ»ΠΈ массив. Π›ΡƒΡ‡ΡˆΠ΅ всСго ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ структуру, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΠ»ΠΈΡΡŒ Π±Ρ‹ "ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹", ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ.

Благодаря Π½Π°Π»ΠΈΡ‡ΠΈΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° появляСтся Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. ВсС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΊΠΎΠ΄, Π½ΠΎ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, привСдСнная Π² листингС 4.2, Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€. На этот Ρ€Π°Π· ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°: ΠΎΠ΄ΠΈΠ½ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ символы 'x', Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” символы 'o'. Π§Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π²ΠΎΠ΄ Π½Π° экран Π½Π΅ длился бСсконСчно, ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ пСрСдаСтся Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠΉ, сколько Ρ€Π°Π· слСдуСт ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ΡŒ символ. Одна ΠΈ Ρ‚Π° ΠΆΠ΅ функция char_print() эксплуатируСтся ΠΎΠ±ΠΎΠΈΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, Π½ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· Π½ΠΈΡ… конфигурируСтся нСзависимо с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ структуры char_print_parms.

Листинг 4.2. (thread-create2.c) Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

#include <pthread.h>

#include <stdio.h>


/* ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ char_print(). */

struct char_print_parms {

 /* ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹ΠΉ символ. */

 char character;

 /* Бколько Ρ€Π°Π· Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ΡŒ. */

 int count;

};


/* Π—Π°ΠΏΠΈΡΡŒ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ числа символов Π² ΠΏΠΎΡ‚ΠΎΠΊ stderr. АргумСнт

   PARAMETERS являСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π½Π° структуру char_print_parms. */

void* char_print(void* parameters) {

 /* ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ указатСля ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ. */

 struct char_print_parms* p =

  (struct char_print_parms*)parameters;

 int i;

 for (i = 0; i < p->count; ++i)

  fputc(p->character, stderr);

 return NULL;

}


/* Основная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°. */

int main() {

 pthread_t thread1_id;

 pthread_t thread2_id;

 struct char_print_parms thread1_args;

 struct char_print_parms thread2_args;


 /* Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰Π΅Π³ΠΎ 30000

    символов 'x'. */

 thread1_args.character = 'x';

 thread1_args.count = 30000;

 pthread_create(&thread1_id, NULL, &char_print, &thread1_args);


 /* Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰Π΅Π³ΠΎ 20000

    символов 'o'. */

 thread2_args.character = 'o';

 thread2_args.count = 20000;

 pthread_create(&thread2_id, NULL, &char_print, &thread2_args);

 return 0;

}

Но постойтС! ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ. Основной ΠΏΠΎΡ‚ΠΎΠΊ (Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰ΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ main()) создаСт структуры thread1_args ΠΈ thread2_args Π² Π²ΠΈΠ΄Π΅ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Π½ΠΈΡ… Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. Π§Ρ‚ΠΎ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ Linux Ρ€Π°ΡΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ функция main() Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»Π°ΡΡŒ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄ΡƒΡ‚ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Ρ‹ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°? НичСго! Но Ссли это ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, структуры окаТутся ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΈΠ· памяти, хотя ΠΎΠ±Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° всС Π΅Ρ‰Π΅ ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ Π½Π° Π½ΠΈΡ….

4.1.2. ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Одно ΠΈΠ· Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ описанной Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ main() Π΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΎΠ±ΠΎΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². НуТна лишь функция Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ wait(), которая Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π½Π΅ с процСссами, Π° с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. Вакая функция называСтся pthread_join(). Она ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°: ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ void*, Π² ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π±ΡƒΠ΄Π΅Ρ‚ записано Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ. Если послСднСС Π½Π΅ Π²Π°ΠΆΠ½ΠΎ, Π·Π°Π΄Π°ΠΉΡ‚Π΅ Π² качСствС Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° NULL.