Визуализация работы потоков
Следующий пример иллюстрирует параллельность выполнения потоков, используя возможности библиотеки графических примитивов 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()
go_b.config(bg=champion) # Кнопка окрашивается в цвет победителя
tk.update_idletasks()
Примечание:
Эта программа использует некоторые возможности языка Python 2.3 (встроенную функцию sum() и списковые включения), поэтому для ее выполнения нужен Python версии не меньше 2.3.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОК