Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² Threading (python) с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ

*ΠŸΠΎΡ‚ΠΎΠΊ (Thread) - это наимСньшая Π΅Π΄ΠΈΠ½ΠΈΡ†Π° исполнСния Π² Ρ€Π°ΠΌΠΊΠ°Ρ… процСсса ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы. ΠŸΠΎΡ‚ΠΎΠΊ выполняСт инструкции ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, прСдставляСт собой ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ процСссор ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса.

Π’Π°ΠΆΠ½Ρ‹Π΅ характСристики ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²:

  1. ΠŸΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ процСссу: ΠŸΠΎΡ‚ΠΎΠΊΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… процСсса ΠΈ Ρ€Π°Π·Π΄Π΅Π»ΡΡŽΡ‚ рСсурсы этого процСсса, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΏΠ°ΠΌΡΡ‚ΡŒ, Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ дСскрипторы ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ систСмныС рСсурсы.
  2. ΠŸΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅: ΠŸΠΎΡ‚ΠΎΠΊΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ процСссС ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ выполняСмыми ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎ Π½Π° многоядСрных ΠΈΠ»ΠΈ многопроцСссорных систСмах.
  3. ЛСгковСсны: ΠŸΠΎΡ‚ΠΎΠΊΠΈ ΠΎΠ±Π»Π°Π΄Π°ΡŽΡ‚ лСгковСсной структурой ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с процСссами. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅, ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ мСньшС систСмных рСсурсов, Ρ‡Π΅ΠΌ для процСссов.
  4. Бинхронизация: ΠŸΠΎΡ‚ΠΎΠΊΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ ΠΈ Ρ€Π°Π·Π΄Π΅Π»ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅. Однако, для обСспСчСния синхронизации доступа ΠΊ ΠΎΠ±Ρ‰ΠΈΠΌ рСсурсам трСбуСтся ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π°Ρ синхронизация для избСТания ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ с состояниСм Π³ΠΎΠ½ΠΊΠΈ (race conditions) ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ выполнСния.

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

ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ - это ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, Ρ‡Ρ‚ΠΎ позволяСт ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ Ρ†Π΅Π»ΠΈ использования многопоточности Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚:

  1. Π£Π²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ: ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ позволяСт Ρ€Π°ΡΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ части Π·Π°Π΄Π°Ρ‡ΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ нСсколькими ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ для ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ выполнСния, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

  2. ΠŸΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΠ΅ отзывчивости: ИспользованиС ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Ρ€Π΅Π°Π³ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° внСшниС события ΠΈΠ»ΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ Π±Π΅Π· Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ основного ΠΏΠΎΡ‚ΠΎΠΊΠ° выполнСния.

  3. Π£Π»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ многозадачности: ΠœΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒ позволяСт Π»Π΅Π³Ρ‡Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΈΠΌΠΈ Π² ΠΌΠ°ΡΡˆΡ‚Π°Π±Π°Ρ… Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

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

ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ: НСсмотря Π½Π° прСимущСства многопоточности, использованиС ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Ρ‚ΡŒΡΡ с рядом ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ:

  1. Π“ΠΎΠ½ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… (Race conditions): Когда нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ рСсурс, ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ с ΡΠΎΠ³Π»Π°ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒΡŽ Π΄Π°Π½Π½Ρ‹Ρ….
  2. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΈ Π΄Π΅Π΄Π»ΠΎΠΊΠΈ: ΠΠ΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ использованиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ для синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ Π΄Π΅Π΄Π»ΠΎΠΊΠ°ΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π° ΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅.
  3. ΠžΡ‚Π»Π°Π΄ΠΊΠ° ΠΈ ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅: БлоТности Π² ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ с ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈΠ·-Π·Π° Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ повСдСния ΠΈ слоТности воспроизвСдСния ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ ΠΏΡ€ΠΈ исполнСнии.

Π Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΡΡ‚ΡŒΡŽ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΏΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Π½ΠΎΡΡ‚ΡŒΡŽ:

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

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· этих ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² ΠΈΠΌΠ΅Π΅Ρ‚ свои особСнности ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ Π² зависимости ΠΎΡ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΈ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования многопоточности Π½Π° языкС программирования Python с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ модуля threading: 1: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ запуск Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²:

import threading
# Ѐункция, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ
def print_numbers():
	for i in range(1, 6):
		print(f"Thread {threading.current_thread().name}: {i}")
# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1 = threading.Thread(target=print_numbers, name="Thread 1")
thread2 = threading.Thread(target=print_numbers, name="Thread 2")
# Запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1.start()
thread2.start()
# ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1.join()
thread2.join()
print("Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½.")

2: ИспользованиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ для синхронизации доступа ΠΊ рСсурсу:

import threading
shared_resource = 0
lock = threading.Lock()

def update_resource():
	global shared_resource
	for _ in range(100000):
	lock.acquire()
	shared_resource += 1
	lock.release()
# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1 = threading.Thread(target=update_resource)
thread2 = threading.Thread(target=update_resource)
# Запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1.start()
thread2.start()
# ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1.join()
thread2.join()
print("Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ рСсурса послС Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²:", shared_resource)

3: ИспользованиС условий (conditions) для ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ:

import threading
total = 0
condition = threading.Condition()
def produce():
	global total
	for _ in range(10): # Π¦ΠΈΠΊΠ» для производства Π΄Π°Π½Π½Ρ‹Ρ…
		with condition: # Π’Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΡΠ΅ΠΊΡ†ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ условия
			total += 1 # Π£Π²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ ΠΎΠ±Ρ‰ΠΈΠΉ счСтчик
			condition.notify() # ΠžΠΏΠΎΠ²Π΅Ρ‰Π°Π΅ΠΌ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ

def consume():
	global total
	with condition: # Π’Ρ…ΠΎΠ΄ Π² ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΡΠ΅ΠΊΡ†ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ условия
		condition.wait(timeout=5)# ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅ΠΌ условиС, ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ увСдомлСния ΠΈΠ»ΠΈ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚
		print(f"Total is: {total}")

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
producer_thread = threading.Thread(target=produce)
consumer_thread = threading.Thread(target=consume)

producer_thread.start()
consumer_thread.start()

producer_thread.join()
consumer_thread.join()

print("Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½.")

4: Класс Barrier ΠΈΠ· модуля threading Π² Python прСдоставляСт ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ ΠΏΡƒΡ‚Π΅ΠΌ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΈΡ… Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° всС ΠΏΠΎΡ‚ΠΎΠΊΠΈ достигнут ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ€ΠΎΠ³Π°. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования Barrier:

import threading
def worker(barrier):
	print(f'Thread {threading.current_thread().name} is waiting at the barrier...')
	barrier.wait()
	print(f'Thread {threading.current_thread().name} passed the barrier')

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Barrier для Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
barrier = threading.Barrier(4) 

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1 = threading.Thread(target=worker, args=(barrier,), name='Thread 1')
thread2 = threading.Thread(target=worker, args=(barrier,), name='Thread 2')
thread3 = threading.Thread(target=worker, args=(barrier,), name='Thread 3')
thread4 = threading.Thread(target=worker, args=(barrier,), name='Thread 4')
thread1.start()
thread2.start()
thread3.start()
thread4.start()

# ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
thread1.join()
thread2.join()
thread3.join()
thread4.join()
print('All threads have passed the barrier')

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π±Π°Ρ€ΡŒΠ΅Ρ€ΠΎΠΌ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· Π½ΠΈΡ… ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚, ΠΏΠΎΠΊΠ° Π½Π΅ всС Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½Π΅ достигнут Π±Π°Ρ€ΡŒΠ΅Ρ€Π°. Когда всС Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ° достигнут этой Ρ‚ΠΎΡ‡ΠΊΠΈ, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ своС Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅. ΠŸΡ€ΠΈ запускС этого ΠΊΠΎΠ΄Π° Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° всС ΠΎΠ½ΠΈ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π³ΠΎΡ‚ΠΎΠ²Ρ‹, послС Ρ‡Π΅Π³ΠΎ вывСдСтся сообщСниС ΠΎ ΠΏΡ€ΠΎΡ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ Π±Π°Ρ€ΡŒΠ΅Ρ€Π° всСми ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ.

5: Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π½ΠΈΠΆΠ΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Semaphore, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠΌΡƒ количСству элСмСнтов Π² спискС, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΊΠ°ΠΊ ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс для ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²:

import threading
import time

# Бписок ΠΊΠ°ΠΊ ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс
shared_resource = []
max_items = 5
# Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ сСмафора
semaphore = threading.Semaphore(max_items)

# ΠŸΠΎΡ‚ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ элСмСнты Π² ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс
def producer():
for i in range(10):
	with semaphore:
		shared_resource.append(i)
		print(f'Producer added {i} to the shared resource')
		time.sleep(1) # ΠŸΠΎΠ΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ врСмя

# ΠŸΠΎΡ‚ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄Π°Π»ΡΡ‚ΡŒ элСмСнты ΠΈΠ· ΠΎΠ±Ρ‰Π΅Π³ΠΎ рСсурса
def consumer():
	for i in range(5):
		with semaphore:
			item = shared_resource.pop(0) if shared_resource else None
			if item is not None:
				print(f'Consumer removed {item} from the shared resource')
			else:
				print('Consumer found the shared resource empty')
			time.sleep(1) # ΠŸΠΎΠ΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ врСмя

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

# Запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
producer_thread.start()
consumer_thread.start()

# ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
producer_thread.join()
consumer_thread.join()
print('All threads have completed their tasks')

ОбъяснСниС:

  1. Semaphore ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ограничСния доступа ΠΊ ΠΎΠ±Ρ‰Π΅ΠΌΡƒ рСсурсу shared_resource, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС прСдставляСт собой список.
  2. ΠŸΠΎΡ‚ΠΎΠΊ producer добавляСт элСмСнты Π² список, ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½Ρ‹ΠΉ Π΄ΠΎ max_items элСмСнтов.
  3. ΠŸΠΎΡ‚ΠΎΠΊ consumer удаляСт элСмСнты ΠΈΠ· списка. Он Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… сСмафора, позволяя Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ с ΠΎΠ±Ρ‰ΠΈΠΌ рСсурсом.
  4. Semaphore Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ max_items элСмСнтов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ‹ ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹ ΠΈΠ· shared_resource.
  5. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² выводится сообщСниС ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ всСх Π·Π°Π΄Π°Ρ‡. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π±ΠΎΠ»Π΅Π΅ ясно дСмонстрируСт Ρ€Π°Π±ΠΎΡ‚Ρƒ Semaphore с ΠΎΠ±Ρ‰ΠΈΠΌ рСсурсом (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС - списком) для контроля доступа ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΊ Π½Π΅ΠΌΡƒ.

6: ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования события (Event) для синхронизации ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»Π΅ΠΉ ΠΈ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»Π΅ΠΉ :

import threading
import time

shared_resource = [] # ΠžΠ±Ρ‰ΠΈΠΉ рСсурс (ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ)
event = threading.Event() # Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Event для синхронизации

# Ѐункция производитСля
def producer():
	for i in range(10):
		shared_resource.append(i)
		print(f"Producer added {i} to the shared resource")
		time.sleep(1)
		event.set() # УстанавливаСм событиС послС добавлСния элСмСнта

# Ѐункция потрСбитСля
def consumer():
	while True:
		event_is_set = event.wait(timeout=1) # ОТиданиС события с Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ΠΎΠΌ 1 сСкунда
		if event_is_set and shared_resource:
			consumed_item = shared_resource.pop(0)
			print(f"Consumer removed {consumed_item} from the shared resource") 
			time.sleep(1)
		elif not shared_resource and event_is_set:
			print("Consumer found the shared resource empty")
			break # Π’Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· Ρ†ΠΈΠΊΠ»Π°, Ссли ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс пуст ΠΈ событиС установлСно 

# Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈ запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()
# ОТиданиС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ производитСля ΠΈ потрСбитСля
producer_thread.join()
event.set() # Установка события для прСдотвращСния Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ потрСбитСля 
consumer_thread.join()
print("All threads have completed their tasks")

ОбъяснСниС:

  1. producer() - функция производитСля, Π΄ΠΎΠ±Π°Π²Π»ΡΡŽΡ‰Π°Ρ элСмСнты Π² ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс.
  2. consumer() - функция потрСбитСля, мониторящая ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс ΠΈ ΡƒΠ΄Π°Π»ΡΡŽΡ‰Π°Ρ элСмСнты. ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΊ Π±Π»ΠΎΠΊΡƒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, Ссли ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅Ρ‚ пустоту ΠΎΠ±Ρ‰Π΅Π³ΠΎ рСсурса ΠΈ установлСнноС событиС.
  3. Π’ основном ΠΏΠΎΡ‚ΠΎΠΊΠ΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΈ Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠΈ производитСля ΠΈ потрСбитСля.
  4. ПослС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ производитСля устанавливаСтся событиС, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ потрСбитСля.
  5. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ±Ρ‰ΠΈΠΉ рСсурс пуст ΠΈ событиС установлСно.
  6. Выводится сообщСниС ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ всСх Π·Π°Π΄Π°Ρ‡ послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².