Рассмотрим следующий пример
from time import sleep
import matplotlib.pyplot as plt
from threading import Thread
import numpy as np
class Monitor(Thread):
def __init__(self):
Thread.__init__(self)
_, self.ax = plt.subplots()
self.data = []
def add_point(self, pt):
self.data.append(pt)
self.ax.cla()
self.ax.plot(self.data)
plt.draw()
class Main_job(Thread):
def __init__(self, monitor):
Thread.__init__(self)
self.monitor = monitor
self.output = []
def run(self):
for i in range(20):
print(i)
pt = np.random.rand()
self.output.append(pt)
self.monitor.add_point(pt)
sleep(1)
monitor = Monitor()
monitor.start()
main = Main_job(monitor)
main.start()
У меня есть поток Main_job
, который выполняет длительную операцию, и я хочу отслеживать его время выполнения.
Поэтому я определил Thread
для цифры matplotlib
и еще один для моего процесса.
Код работает нормально
Предположим теперь, что я хочу что-то сделать с выводом потока Main_job
перед закрытием программы (например, распечатать ее или сохранить в файл).
Я добавляю следующие строки в конце моего code
main.join()
print(main.output)
Однако это как-то мешает matplotlib
, что, несмотря на то, что поток monitor
вообще не изменяется, теперь зависает до завершения main
.
Как мне дождаться окончания main
до sh, но в то же время избегать зависания monitor
?
РЕДАКТИРОВАТЬ 1 - Однопоточная (нерабочая) версия
По запросу FiddleStix приведена однопотоковая версия кода. Несмотря на то, что эта версия намного проще, в этой версии фигура зависает и отображается только в конце процесса
from time import sleep
import matplotlib.pyplot as plt
import numpy as np
_, ax = plt.subplots()
output = []
for i in range(20):
print(i)
pt = np.random.rand()
output.append(pt)
ax.cla()
ax.plot(output)
sleep(1)
Ситуацию можно немного улучшить, добавив plt.pause(0.01)
после построения графика. Таким образом, однако, фигура отображается, но пользователь может взаимодействовать только в течение этих 0,01 с.
ПРИМЕЧАНИЕ. Я знаю, что проблему можно решить, заменив sleep(1)
на plt.pause(1)
, но здесь sleep
- это только прокси для длительной длительной операции в реальном коде, а не просто пауза .