我不等待

时间:2018-04-16 12:21:50

标签: python matplotlib multiprocessing python-multiprocessing

关于这个主题有很多问题,但显然没有我的确切用例。

我正在运行一个长循环,每次迭代都需要花费很多时间。我想在每个循环图的末尾(使用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个工作,并且绘图太慢 - 是否有办法删除最老的工作,以便我们有机会赶上``外部流程''?

1 个答案:

答案 0 :(得分:1)

关于第一个问题,你的假设是错误的。在您致电apply_async后立即进行实际计算。方法返回的AsyncResult对象可用于检索计算结果。它会一直阻止,直到它们准备就绪,但如果你愿意,你可以忽略它。

请注意,如果您不收集AsyncResult,则plotStuff中触发的错误将被忽略。如果您仍想报告错误,可以在调用apply_async时设置回调函数并在那里打印错误消息。

对于问题的第二部分,我谨请你们更好地阐述,因为你们想要实现的目标并不是很清楚。