考虑以下示例
similar_products
我有一个ILIKE '%\_WIN\_%' ESCAPE '\'
线程执行一个冗长的操作,并且我想监视它的运行时。
因此,我为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
,尽管根本没有修改main.join()
print(main.output)
线程,但现在挂起直到matplotlib
完成。
如何等待monitor
完成,但同时又避免main
挂起?
在FiddleStix请求之后,这是代码的单线程版本。尽管简单得多,但在此版本中,该图仍然挂起并且仅在过程结束时显示
main
在绘制后添加monitor
可以稍微改善这种情况。但是,通过这种方式可以显示图形,但是用户只能在0.01s内进行交互。
注意:我知道可以用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)
来解决问题,但是这里sleep(1)
只是长时间执行真实代码中的操作的代理,而不是只是一个停顿。
答案 0 :(得分:0)
我认为您想使Monitor线程成为daemon
线程(docs)。如果主线程停止,则守护程序线程将自动退出。这样,您可以在后台运行某些程序,而无需显式停止第二个线程。
您只需添加类参数即可将线程声明为守护程序:
class Monitor(Thread):
daemon = True
答案 1 :(得分:0)
GUI mainloop应该在主线程中运行。在一个单独的线程中运行您的作业,以免阻塞GUI。
通过在线程中使用matplotlib.pyplot.draw执行重绘,可以实现随着output
的变化而绘制的简单动画。
请考虑使用Animation API来平滑地绘制实时图。
from time import sleep
import matplotlib.pyplot as plt
from threading import Thread
import numpy as np
_, ax = plt.subplots()
output = []
class Job(Thread):
def run(self):
for i in range(10):
print(i)
pt = np.random.rand()
output.append(pt)
sleep(1)
ax.cla()
ax.plot(output)
plt.draw()
job = Job()
job.start()
plt.show()