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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования PythonΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 45

Автор Π ΠΎΠΌΠ°Π½ Π‘ΡƒΠ·ΠΈ

def hello():

 print "Hello, world!"


t = Timer(30.0, hello)

t.start()

Π—Π°ΠΌΠΊΠΈ

ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΠΉ Π·Π°ΠΌΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π½Π° основС класса Lock модуля threading. Π—Π°ΠΌΠΎΠΊ ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° состояния: ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚, ΠΈΠ»ΠΈ Π·Π°ΠΏΠ΅Ρ€Ρ‚. Π’ послСднСм случаС ΠΈΠΌ Π²Π»Π°Π΄Π΅Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ класса Lock ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹:

β€’ acquire([blocking=True]) Π”Π΅Π»Π°Π΅Ρ‚ запрос Π½Π° Π·Π°ΠΏΠΈΡ€Π°Π½ΠΈΠ΅ Π·Π°ΠΌΠΊΠ°. Если ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ blocking Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ ΠΈΠ»ΠΈ являСтся истиной, Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ освобоТдСния Π·Π°ΠΌΠΊΠ°. Если ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π½Π΅ Π±Ρ‹Π» Π·Π°Π΄Π°Π½, ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ значСния. Если blocking Π±Ρ‹Π» Π·Π°Π΄Π°Π½ ΠΈ истинСн, ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ True (послС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ овладСния Π·Π°ΠΌΠΊΠΎΠΌ). Если Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π½Π΅ трСбуСтся (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π·Π°Π΄Π°Π½ blocking=False), ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Π΅Ρ€Π½Π΅Ρ‚ True, Ссли Π·Π°ΠΌΠΎΠΊ Π½Π΅ Π±Ρ‹Π» Π·Π°ΠΏΠ΅Ρ€Ρ‚ ΠΈ ΠΈΠΌ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΎΠ²Π»Π°Π΄Π΅Π» Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΎ False.

β€’ release() Запрос Π½Π° ΠΎΡ‚ΠΏΠΈΡ€Π°Π½ΠΈΠ΅ Π·Π°ΠΌΠΊΠ°.

β€’ locked() Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС Π·Π°ΠΌΠΊΠ° (True β€” Π·Π°ΠΏΠ΅Ρ€Ρ‚, False β€” ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚). Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ Π² Π²ΠΈΠ΄Ρƒ, Ρ‡Ρ‚ΠΎ Π΄Π°ΠΆΠ΅ Ссли состояниС Π·Π°ΠΌΠΊΠ° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½ΠΎ, это Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½ сохранит это состояниС Π΄ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹.

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π·Π°ΠΌΠΊΠ° β€” threading.RLock, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ отличаСтся ΠΎΡ‚ threading.Lock Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ Π·Π°ΠΏΠΈΡ€Π°Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·. ΠžΡ‚ΠΏΠΈΡ€Π°Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΎΠ³ΠΎ Π·Π°ΠΌΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΈΡΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΆΠ΅ Ρ€Π°Π·, сколько Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΠΈΡ€Π°Π½ΠΈΠΉ. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Π½ΡƒΡ‚Ρ€ΠΈ рСкурсивных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.

Когда Π½ΡƒΠΆΠ½Ρ‹ Π·Π°ΠΌΠΊΠΈ?

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

Вупиковая ситуация (deadlock)

Π—Π°ΠΌΠΊΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ для управлСния доступом ΠΊ рСсурсу, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ нСльзя ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ совмСстно. Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Ρ‚Π°ΠΊΠΈΡ… рСсурсов ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ нСсколько. ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π·Π°ΠΌΠΊΠ°ΠΌΠΈ Π²Π°ΠΆΠ½ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΏΡ€ΠΎΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ, Π½Π΅ Π·Π°ΠΉΠ΄Π΅Ρ‚ Π»ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² Ρ‚ΡƒΠΏΠΈΠΊ (deadlock) из–за Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π΄Π²ΡƒΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ ΠΏΠΎΡ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ рСсурсы, Π½ΠΎ Π½ΠΈ Ρ‚ΠΎΡ‚, Π½ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π½Π΅ смогут ΠΈΡ… ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ ΡƒΠΆΠ΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ Π·Π°ΠΌΠΊΠΈ. Вакая ситуация ΠΏΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π° Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

import threading, time


resource = {'A': threading.Lock(), 'B': threading.Lock()}


def proc(n, rs):

 for r in rs:

  print "ΠŸΡ€ΠΎΡ†Π΅ΡΡ %s Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ рСсурс %s" % (n, r)

  resource[r].acquire()

  print "ΠŸΡ€ΠΎΡ†Π΅ΡΡ %s ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» рСсурс %s" % (n, r)

  time.sleep(1)

 print "ΠŸΡ€ΠΎΡ†Π΅ΡΡ %s выполняСтся" % n

 for r in rs:

  resource[r].release()

 print "ΠŸΡ€ΠΎΡ†Π΅ΡΡ %s Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ» Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅" % n


p1 = threading.Thread(target=proc, name="t1", args=["1", "AB"])

p2 = threading.Thread(target=proc, name="t2", args=["2", "BA"])

p1.start()

p2.start()

p1.join()

p2.join()

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° (t1 ΠΈ t2) Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽΡ‚ Π·Π°ΠΌΠΊΠΈ ΠΊ ΠΎΠ΄Π½ΠΈΠΌ ΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ рСсурсам (A ΠΈ B), Π½ΠΎ Π² Ρ€Π°Π·Π½ΠΎΠΌ порядкС, ΠΎΡ‚Ρ‡Π΅Π³ΠΎ получаСтся, Ρ‡Ρ‚ΠΎ Π½ΠΈ Ρƒ Ρ‚ΠΎΠ³ΠΎ, Π½ΠΈ Ρƒ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π½Π΅ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚ рСсурсов для дальнСйшСй Ρ€Π°Π±ΠΎΡ‚Ρ‹, ΠΈ ΠΎΠ½ΠΈ ΠΎΠ±Π° Π±Π΅Π·Π½Π°Π΄Π΅ΠΆΠ½ΠΎ ΠΏΠΎΠ²ΠΈΡΠ°ΡŽΡ‚, оТидая освобоТдСния Π½ΡƒΠΆΠ½ΠΎΠ³ΠΎ рСсурса. Благодаря ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌ print ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ событий:

ΠŸΡ€ΠΎΡ†Π΅ΡΡ 1 Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ рСсурс A

ΠŸΡ€ΠΎΡ†Π΅ΡΡ 1 ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» рСсурс A

ΠŸΡ€ΠΎΡ†Π΅ΡΡ 2 Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ рСсурс B

ΠŸΡ€ΠΎΡ†Π΅ΡΡ 2 ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» рСсурс B

ΠŸΡ€ΠΎΡ†Π΅ΡΡ 1 Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ рСсурс B

ΠŸΡ€ΠΎΡ†Π΅ΡΡ 2 Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ рСсурс A

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠΈ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Ρ… Ρ‚ΡƒΠΏΠΈΠΊΠΎΠ², ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΈΡ… рассмотрСниС Π½Π΅ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² Ρ€Π°ΠΌΠΊΠΈ Π΄Π°Π½Π½ΠΎΠΉ Π»Π΅ΠΊΡ†ΠΈΠΈ. МоТно ΠΏΠΎΡΠΎΠ²Π΅Ρ‚ΠΎΠ²Π°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΈΠ΅ΠΌΡ‹:

β€’ ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π»ΠΎΠ³ΠΈΠΊΡƒ прилоТСния Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ Π·Π°ΠΌΠΊΠΈ ΠΊ Π΄Π²ΡƒΠΌ рСсурсам сразу. Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, придСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ составной рСсурс. Π’ частности, ΠΊ Π΄Π°Π½Π½ΠΎΠΌΡƒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π·Π°ΠΌΠΎΠΊ Β«ABΒ» для указания эксклюзивного доступа ΠΊ рСсурсам A ΠΈ B.

β€’ ΡΡ‚Ρ€ΠΎΠ³ΠΎ ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡ΠΈΡ‚ΡŒ всС рСсурсы (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎ Ρ†Π΅Π½Π΅) ΠΈ всСгда Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ порядкС (скаТСм, начиная с Π±ΠΎΠ»Π΅Π΅ Π΄ΠΎΡ€ΠΎΠ³ΠΈΡ… рСсурсов). ΠŸΡ€ΠΈ этом ΠΏΠ΅Ρ€Π΅Π΄ Π·Π°ΠΊΠ°Π·ΠΎΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ рСсурса ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡ‚ΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΈΠΌ Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΡˆΠ΅Π²Ρ‹Ρ… рСсурсов.

Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹

Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹ (ΠΈΡ… ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ сСмафорами Дийкстры (Dijkstra) ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΈΡ… изобрСтатСля) ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±Ρ‰ΠΈΠΌ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π½Π΅ΠΆΠ΅Π»ΠΈ Π·Π°ΠΌΠΊΠΈ. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π² ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ сразу нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€ ΠΈΠΌΠ΅Π΅Ρ‚ счСтчик запросов, ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°ΡŽΡ‰ΠΈΠΉΡΡ с ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° acquire() ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉΡΡ ΠΏΡ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ release(). Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ мСньшС нуля, поэтому Π² Ρ‚Π°ΠΊΠΎΠΌ состоянии ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ приходится ΠΆΠ΄Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΈ Π² случаС с Π·Π°ΠΌΠΊΠ°ΠΌΠΈ, ΠΏΠΎΠΊΠ° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π½Π΅ увСличится.

ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ класса threading.Semaphore ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС (Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ) Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ состояниС счСтчика (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΠ½ΠΎ Ρ€Π°Π²Π½ΠΎ 1, Ρ‡Ρ‚ΠΎ соотвСтствуСт Π·Π°ΠΌΠΊΡƒ класса Lock). ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ acquire() ΠΈ release() Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‚ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ описанным Π²Ρ‹ΡˆΠ΅ ΠΎΠ΄Π½ΠΎΠΈΠΌΠ΅Π½Π½Ρ‹ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ Ρƒ Π·Π°ΠΌΠΊΠΎΠ².

Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ для ΠΎΡ…Ρ€Π°Π½Ρ‹ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ рСсурса. НапримСр, с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠΎΠΆΠ½ΠΎ вСсти ΠΏΡƒΠ» соСдинСний с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ‚Π°ΠΊΠΎΠ³ΠΎ использования сСмафора (заимствован ΠΈΠ· Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ ΠΊ Python) Π΄Π°Π½ Π½ΠΈΠΆΠ΅:

from threading import BoundedSemaphore

maxconnections = 5

# ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° сСмафора

pool_sema = BoundedSemaphore(value=maxconnections)


# Π’Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°:


pool_sema.acquire()

conn = connectdb()

# ... использованиС соСдинСния ...

conn.close()

pool_sema.release()

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, примСняСтся Π½Π΅ Π±ΠΎΠ»Π΅Π΅ пяти соСдинСний с Π±Π°Π·ΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ…. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ использован класс threading.BoundedSemaphore. ЭкзСмпляры этого класса ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ ΠΎΡ‚ экзСмпляров класса threading.Semaphore Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ Π΄Π°ΡŽΡ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ release() большС, Ρ‡Π΅ΠΌ сдСлан acquire().

Бобытия

Π•Ρ‰Π΅ ΠΎΠ΄Π½ΠΈΠΌ способом ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ события. ЭкзСмпляры класса threading.Event ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ наступлСнии Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ события ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈΠ»ΠΈ нСскольким Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹β€“ΡΠΎΠ±Ρ‹Ρ‚ΠΈΡ ΠΈΠΌΠ΅ΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ Ρ„Π»Π°Π³, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² установлСнном ΠΈΠ»ΠΈ ΡΠ±Ρ€ΠΎΡˆΠ΅Π½Π½ΠΎΠΌ состоянии. ΠŸΡ€ΠΈ своСм создании Ρ„Π»Π°Π³ события находится Π² ΡΠ±Ρ€ΠΎΡˆΠ΅Π½Π½ΠΎΠΌ состоянии. Если Ρ„Π»Π°Π³ Π² установлСнном состоянии, оТидания Π½Π΅ происходит: ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹Π·Π²Π°Π²ΡˆΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ wait() для оТидания события, просто ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ. НиТС ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ экзСмпляров класса threading.Event:

β€’ set() УстанавливаСт Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ Ρ„Π»Π°Π³, ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΎ наступлСнии события. ВсС ΠΆΠ΄ΡƒΡ‰ΠΈΠ΅ Π΄Π°Π½Π½ΠΎΠ³ΠΎ события ΠΏΠΎΡ‚ΠΎΠΊΠΈ выходят ΠΈΠ· состояния оТидания.

β€’ clear() БбрасываСт Ρ„Π»Π°Π³. ВсС события, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ wait() этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°β€“ΡΠΎΠ±Ρ‹Ρ‚ΠΈΡ, Π±ΡƒΠ΄ΡƒΡ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π² состоянии оТидания Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Ρ„Π»Π°Π³ ΡΠ±Ρ€ΠΎΡˆΠ΅Π½, ΠΈΠ»ΠΈ ΠΏΠΎ истСчСнии Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Π°.

β€’ isSet() Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ состояниС Ρ„Π»Π°Π³Π°.

β€’ wait([timeout]) ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π² состояниС оТидания, Ссли Ρ„Π»Π°Π³ ΡΠ±Ρ€ΠΎΡˆΠ΅Π½, ΠΈ сразу возвращаСтся, Ссли Ρ„Π»Π°Π³ установлСн. АргумСнт timeout Π·Π°Π΄Π°Π΅Ρ‚ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ Π² сСкундах, ΠΏΠΎ истСчСнии ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ прСкращаСтся, Π΄Π°ΠΆΠ΅ Ссли событиС Π½Π΅ наступило.

Π‘ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с событиями прСдлагаСтся Π² качСствС упраТнСния.

Условия

Π‘ΠΎΠ»Π΅Π΅ слоТным ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΎΠΌ ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ являСтся ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ условий. Условия ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅ экзСмпляров класса threading.Condition ΠΈ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ рассмотрСнным событиям, ΠΎΠΏΠΎΠ²Π΅Ρ‰Π°ΡŽΡ‚ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ состояния. ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€ класса threading.Condition ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€, Π·Π°Π΄Π°ΡŽΡ‰ΠΈΠΉ Π·Π°ΠΌΠΎΠΊ класса threading.Lock ΠΈΠ»ΠΈ threading.RLock. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ создаСтся Π½ΠΎΠ²Ρ‹ΠΉ экзСмпляр Π·Π°ΠΌΠΊΠ° класса threading.RLock. ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°β€“ΡƒΡΠ»ΠΎΠ²ΠΈΡ описаны Π½ΠΈΠΆΠ΅:

β€’ acquire(...) Π—Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Π·Π°ΠΌΠΎΠΊ. ЀактичСски вызываСтся ΠΎΠ΄Π½ΠΎΠΈΠΌΠ΅Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒβ€“ΡƒΡΠ»ΠΎΠ²ΠΈΡŽ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°β€“Π·Π°ΠΌΠΊΠ°.