β’ 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()