如何从多个流程向主流程报告结果?

时间:2014-02-13 16:45:36

标签: python multiprocessing

我目前有18个函数可以对大型XML文件执行不同的验证集。我创建了一个扩展ValidationWarning的自定义UserWarning类,这些函数会针对每个验证失败发出警告。最后,我需要生成一个包含所有失败的XLSX报告(ValidationWarning对象中提供了每个失败的标识信息。)

我打算为每个函数生成一个进程(我看到了将任务放在JoinableQueue中的示例,但我不明白为什么这是必要的,除非以后修改任务列表) 。验证失败的顺序无关紧要,在完成所有验证之前,我不需要查看结果。我应该替换每个验证函数的showwarning()函数来写入list返回的Manager()吗?加入所有进程后,我可以将结果导出到XLSX。这比写Queue更好吗? Queue可能会更快,但写作结果不是瓶颈,我不明白我是如何解决以下问题的(请参阅http://docs.python.org/2/library/multiprocessing.html#programming-guidelines):

  

这意味着无论何时使用队列,您都需要确保在加入进程之前最终删除已放入队列的所有项目。否则,您无法确定已将项目放入队列的进程将终止。

我忽略了一种更好的方法吗?根据我的理解,我不能在主进程中使用catch_warnings上下文管理器,并希望它能从每个验证过程中捕获警告,尽管我还没有测试过它(编辑:我测试了它,并且,as预期,它失败了)。直接写入XLSX而不是首先获得所有结果听起来也很困难,因为我需要创建一个空白的XLSX文件并在管理对共享XLSX文件的访问时在每个进程中更新它。

谢谢!

1 个答案:

答案 0 :(得分:1)

我在同一家公司工作,在公司邮件列表上看到了你的邮件:)

你为什么不尝试这样的事情:

from multiprocessing import Pool
from time import sleep
import warnings

def catchwarnings(arg):
    msg, num = arg
    with warnings.catch_warnings(record=True) as w:
        if num == 4:
            sleep(10)
        print 'catchfxn called with num=%d' % num
        warnings.simplefilter("always")

        # Trigger a warning.
        for i in xrange(num):
            warnings.warn("{} - #{}".format(msg, i), UserWarning)
    return w

def printwarnings(w):
    print w

if __name__=='__main__':
    p = Pool(18)
    for i in [('waaa', 3), ('squeee', 4), ('maaaa', 2)]:
        p.apply_async(catchwarnings, args=(i, ), callback=printwarnings)
    p.close()
    p.join()

给出这个:

catchfxn called with num=3
catchfxn called with num=2
[<warnings.WarningMessage object at 0x10559a4d0>, <warnings.WarningMessage object at    0x10559a710>, <warnings.WarningMessage object at 0x10559a750>]
[<warnings.WarningMessage object at 0x10559a510>, <warnings.WarningMessage object at 0x10559a550>]
catchfxn called with num=4
[<warnings.WarningMessage object at 0x10559a650>, <warnings.WarningMessage object at 0x10559a690>, <warnings.WarningMessage object at 0x10559a4d0>, <warnings.WarningMessage object at 0x10559a710>]

使用回调代码更清晰。