我目前有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文件的访问时在每个进程中更新它。
谢谢!
答案 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>]
使用回调代码更清晰。