关于这个主题有很多问题,但显然没有我的确切用例。
我正在运行一个很长的循环,每次迭代都需要花费大量时间。我想在每个循环图的末尾(使用matplotlib
)显示当前进度。基本设置是
import matplotlib.pyplot as plt
def plotStuff(data)
plt.figure()
plt.plot(data)
plt.savefig('test.pdf')
def main():
for iteration in range(1000):
data = doStuff(oldData)
if convergence(data, oldData):
break
plotStuff(data)
oldData = data
if __name__ == '__main__':
main()
但是,绘图例程需要花费大量时间。我最初的解决方案是
import threading
并将打印部分更改为
plottingThread = threading.Thread(target=plotStuff, args=data)
plottingThread.start()
但是,似乎matplotlib
不是线程保存。我的最新想法是
import multiprocessing
和
def main():
pool = multiprocessing.Pool(processes=1)
for iteration in range(1000):
data = doStuff(oldData)
if convergence(data, oldData):
break
res = pool.apply_async(plotStuff, args=(data,))
oldData = data
但是,这似乎只会调度函数调用,而不是实际执行它。执行通过pool.close(); pool.join()
或res.get()
进行。但是,pool.join()
和res.get()
确实会阻止主进程,直到池完成。
我相信我的问题是:我怎样才能异步调用plotStuff(data)
而不必等待结果?
此外,如果有一种方法可以控制池中的作业,我会很高兴。比如说,我只想在池中最多有10
个作业,而且绘图太慢了——有没有办法删除最旧的作业,这样我们就有机会赶上"外部进程"?
关于第一个问题,你的假设是错误的。实际计算在您调用apply_async
后立即发生。该方法返回的AsyncResult
对象可用于检索计算结果。它会阻止,直到他们准备好,但如果你愿意,你可以忽略它。
请记住,如果您不收集AsyncResult
,plotStuff
中触发的错误将被忽视。如果仍想报错,可以在调用apply_async
时设置回调函数,并在其中打印报错信息。
对于问题的第二部分,我恳请您更好地详细说明,因为目前还不清楚您想要实现的目标。