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

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

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

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

β€’ release() Π‘Π½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π°ΠΌΠΎΠΊ.

β€’ wait([timeout]) ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π² Ρ€Π΅ΠΆΠΈΠΌ оТидания. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ случаС, Ссли Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π΅Π³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ» Π·Π°ΠΌΠΎΠΊ. ΠœΠ΅Ρ‚ΠΎΠ΄ снимаСт Π·Π°ΠΌΠΎΠΊ ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎ появлСния объявлСний, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² notify() ΠΈ notifyAll() Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. ΠΠ΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ timeout Π·Π°Π΄Π°Π΅Ρ‚ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚ оТидания Π² сСкундах. ΠŸΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· оТидания ΠΏΠΎΡ‚ΠΎΠΊ снова Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ Π·Π°ΠΌΠΎΠΊ ΠΈ возвращаСтся ΠΈΠ· ΠΌΠ΅Ρ‚ΠΎΠ΄Π° wait().

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

β€’ notifyAll() Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π΅Π½ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ notify(), Π½ΠΎ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ всСх ΠΆΠ΄ΡƒΡ‰ΠΈΡ… выполнСния условия ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ условия ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ для оповСщСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΎ ΠΏΡ€ΠΈΠ±Ρ‹Ρ‚ΠΈΠΈ Π½ΠΎΠ²ΠΎΠΉ ΠΏΠΎΡ€Ρ†ΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… (организуСтся связь ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ β€” ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ, producer β€” consumer):

import threading


cv = threading.Condition()


class Item:

 """ΠšΠ»Π°ΡΡβ€“ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±Π»ΡΡ‚ΡŒΡΡ

 Π² ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ…"""

 def __init__(self):

  self._items = []

 def is_available(self):

  return len(self._items) > 0

 def get(self):

  return self._items.pop()

 def make(self, i):

  self._items.append(i)


item = Item()


def consume():

 """ΠŸΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ элСмСнта (с ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ Π΅Π³ΠΎ появлСния)"""

 cv.acquire()

 while not item.is_available():

  cv.wait()

 it = item.get()

 cv.release()

 return it


def consumer():

 while True:

  print consume()


def produce(i):

 """ЗанСсСниС Π½ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ ΠΈ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²"""

 cv.acquire()

 item.make(i)

 cv.notify()

 cv.release()


p1 = threading.Thread(target=consumer, name="t1")

p1.setDaemon(True)

p2 = threading.Thread(target=consumer, name="t2")

p2.setDaemon(True)

p1.start()

p2.start()

produce("ITEM1")

produce("ITEM2")

produce("ITEM3")

produce("ITEM4")

p1.join()

p2.join()

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ условиС cv ΠΎΡ‚Ρ€Π°ΠΆΠ°Π΅Ρ‚ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… элСмСнтов Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ item. Ѐункция produce() Β«ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Β» элСмСнты, Π° consume(), Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π°Ρ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², «потрСбляСт». Π‘Ρ‚ΠΎΠΈΡ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ закончится, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π΅Ρ‚ бСсконСчный Ρ†ΠΈΠΊΠ» Π² ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ…, Π° Π² Π³Π»Π°Π²Π½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ β€” ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ этих ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π•Ρ‰Π΅ ΠΎΠ΄Π½Π° ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ β€” ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ Π΄Π΅ΠΌΠΎΠ½Π°, установлСнный с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° setDaemon() ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°β€“ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΄ΠΎ Π΅Π³ΠΎ старта.

ΠžΡ‡Π΅Ρ€Π΅Π΄ΡŒ

ΠŸΡ€ΠΎΡ†Π΅ΡΡ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅, ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, достойноС ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ модуля. Π’Π°ΠΊΠΎΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ языка Python Π΅ΡΡ‚ΡŒ, ΠΈ ΠΎΠ½ называСтся Queue.

Помимо ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ β€” Queue.Full (ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½Π°) ΠΈ Queue.Empty (ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ пуста) β€” ΠΌΠΎΠ΄ΡƒΠ»ΡŒ опрСдСляСт класс Queue, Π·Π°Π²Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ собствСнно ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒΡŽ.

БобствСнно, здСсь ΠΌΠΎΠΆΠ½ΠΎ привСсти Π°Π½Π°Π»ΠΎΠ³ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π²Ρ‹ΡˆΠ΅, Π½ΠΎ ΡƒΠΆΠ΅ с использованиСм класса Queue.Queue:

import threading, Queue


item = Queue.Queue()


def consume():

 """ΠŸΠΎΡ‚Ρ€Π΅Π±Π»Π΅Π½ΠΈΠ΅ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ элСмСнта (с ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ Π΅Π³ΠΎ появлСния)"""

 return item.get()


def consumer():

 while True:

  print consume()


def produce(i):

 """ЗанСсСниС Π½ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ ΠΈ ΠΎΠΏΠΎΠ²Π΅Ρ‰Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²"""

 item.put(i)


p1 = threading.Thread(target=consumer, name="t1")

p1.setDaemon(True)

p2 = threading.Thread(target=consumer, name="t2")

p2.setDaemon(True)

p1.start()

p2.start()

produce("ITEM1")

produce("ITEM2")

produce("ITEM3")

produce("ITEM4")

p1.join()

p2.join()

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ всС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ спрятаны Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, поэтому Π² ΠΊΠΎΠ΄Π΅ ΠΎΠ½ΠΈ явным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π½Π΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚.

ΠœΠΎΠ΄ΡƒΠ»ΡŒ thread

По ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΌ threading, ΠΌΠΎΠ΄ΡƒΠ»ΡŒ thread прСдоставляСт Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΉ доступ ΠΊ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. МногиС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ модуля threading, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ рассматривался Π΄ΠΎ этого, Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Π½Π° Π±Π°Π·Π΅ модуля thread. Π—Π΄Π΅ΡΡŒ стоит ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ замСчания ΠΏΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π²ΠΎΠΎΠ±Ρ‰Π΅. ДокумСнтация ΠΏΠΎ Python ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ использованиС ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈΠΌΠ΅Π΅Ρ‚ особСнности:

β€’ Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ KeyboardInterrupt (ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠ΅ ΠΎΡ‚ ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹) ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ Π»ΡŽΠ±Ρ‹ΠΌ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Ссли Π² поставкС Python Π½Π΅Ρ‚ модуля signal (для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сигналов).

β€’ ΠΠ΅ всС встроСнныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ΠΌ Π²Π²ΠΎΠ΄Π°, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ. ΠŸΡ€Π°Π²Π΄Π°, основныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Ρ€ΠΎΠ΄Π΅ time.sleep(), select.select(), ΠΌΠ΅Ρ‚ΠΎΠ΄ read() Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ.

β€’ ΠΠ΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€Π΅Ρ€Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ acquire(), Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ KeyboardInterrupt возбуТдаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° ΠΈΠ· этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π°.

β€’ ΠΠ΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π»ΡΡ Ρ€Π°Π½ΡŒΡˆΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ дСструкторы ΠΈ Π΄Π°ΠΆΠ΅ части finally Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°Ρ… try–finally. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‡Ρ‚ΠΈ всС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ систСмы Π·Π°Π²Π΅Ρ€ΡˆΠ°ΡŽΡ‚ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ Π³Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ.

Визуализация Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ выполнСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ возмоТности Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ графичСских ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ² Tkinter (ΠΎΠ½Π° Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ поставку Python). НСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π½Π°ΠΏΠ΅Ρ€Π΅Π³ΠΎΠ½ΠΊΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°ΡŽΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠ° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Ρ†Π²Π΅Ρ‚Π°. Π¦Π²Π΅Ρ‚ΠΎΠΌ побСдившСго ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΎΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ ΠΊΠ½ΠΎΠΏΠΊΠ° Go:

import threading, time, sys

from Tkinter import Tk, Canvas, Button, LEFT, RIGHT, NORMAL, DISABLED


global champion


# ЗадаСтся дистанция, Ρ†Π²Π΅Ρ‚ полосок ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹

distance = 300

colors = ["Red","Orange","Yellow","Green","Blue","DarkBlue","Violet"]

nrunners = len(colors)     # количСство Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

positions = [0] * nrunners # список Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΡ… ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ

h, h2 = 20, 10             # ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ высоты полосок


def run(n):

 """ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±Π΅Π³Π° n–го участника (ΠΏΠΎΡ‚ΠΎΠΊΠ°)"""

 global champion

 while 1:

  for i in range(10000): # интСнсивныС вычислСния

   pass

  graph_lock.acquire()

  positions[n] += 1            # ΠΏΠ΅Ρ€Π΅Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π½Π° шаг

  if positions[n] == distance: # Ссли ΡƒΠΆΠ΅ Ρ„ΠΈΠ½ΠΈΡˆ

   if champion is None:        # ΠΈ Ρ‡Π΅ΠΌΠΏΠΈΠΎΠ½ Π΅Ρ‰Π΅ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½,

    champion = colors[n]       # назначаСтся Ρ‡Π΅ΠΌΠΏΠΈΠΎΠ½

   graph_lock.release()

   break

  graph_lock.release()


def ready_steady_go():

 """Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π½Π°Ρ‡Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ ΠΈ запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²"""

 graph_lock.acquire()

 for i in range(nrunners):

  positions[i] = 0

  threading.Thread(target=run, args=[i,]).start()

 graph_lock.release()


def update_positions():

 """ОбновлСниС ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΉ"""

 graph_lock.acquire()

 for n in range(nrunners):

  c.coords(rects[n], 0, n*h, positions[n], n*h+h2)

 tk.update_idletasks() # прорисовка ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ

 graph_lock.release()


def quit():

 """Π’Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹"""

 tk.quit()

 sys.exit(0)


# ΠŸΡ€ΠΎΡ€ΠΈΡΠΎΠ²ΠΊΠ° ΠΎΠΊΠ½Π°, основы для ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΎΠ² ΠΈ самих ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΎΠ²,

# ΠΊΠ½ΠΎΠΏΠΎΠΊ для пуска ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π°

tk = Tk()

tk.title("Π‘ΠΎΡ€Π΅Π²Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²")

c = Canvas(tk, width=distance, height=nrunners*h, bg="White")

c.pack()

rects = [c.create_rectangle(0, i*h, 0, i*h+h2, fill=colors[i])

 for i in range(nrunners)]

go_b = Button(text="Go", command=tk.quit)

go_b.pack(side=LEFT)

quit_b = Button(text="Quit", command=quit)

quit_b.pack(side=RIGHT)


# Π—Π°ΠΌΠΎΠΊ, Ρ€Π΅Π³ΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ доступ ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Tk

graph_lock = threading.Lock()


# Π¦ΠΈΠΊΠ» провСдСния сорСвнований

while 1:

 go_b.config(state=NORMAL), quit_b.config(state=NORMAL)

 tk.mainloop() # ОТиданиС наТатия клавиш

 champion = None

 ready_steady_go()

 go_b.config(state=DISABLED), quit_b.config(state=DISABLED)

 # Π“Π»Π°Π²Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΆΠ΄Π΅Ρ‚ Ρ„ΠΈΠ½ΠΈΡˆΠ° всСх участников

 while sum(positions) < distance*nrunners:

  update_positions()

 update_positions()