解决:问题是Wingware Python IDE。我想现在的自然问题是它是如何可行的以及如何解决这个问题。
我昨天问了一个问题(Problem with multiprocessing.Pool in Python),这个问题几乎是一样的,但我发现它似乎可以在Windows电脑上运行,而不是在我的ubuntu上运行。在这篇文章的最后,我将发布一个稍微不同的代码版本,它会做同样的事情。
我的问题的简短摘要:在Python中使用multiprocessing.Pool时,我并不总能获得我要求的工作量。当发生这种情况时,程序就会停止。
我一直在寻找解决方案,然后我开始考虑诺亚斯对我之前的问题的评论。他说它在他的机器上工作,所以我把代码交给我的同事,他运行一台带有Enthoughts 64位Python 2.7.1发行版的Windows机器。我和ubuntu上运行的差别很大。我还提到我们都有Wingware Python IDE,但我怀疑这有什么重要意义吗?
当我的同事在他的机器上运行代码时,我的代码有两个问题。
我并不总能得到我要求的四名工人(虽然我的机器有12名工人)。当发生这种情况时,该过程就会停止并且不会继续。没有异常或引发错误。
当我能够得到我要求的四名工人时(大概发生约1次5次左右),所产生的数字(普通随机数)对于所有四张图片都是完全相同的。我的同事不是这种情况。
有些东西非常可疑,我非常感谢你们提供的任何帮助。
代码:
import multiprocessing as mp
import scipy as sp
import scipy.stats as spstat
import pylab
def testfunc(x0, N):
print 'working with x0 = %s' % x0
x = [x0]
for i in xrange(1,N):
x.append(spstat.norm.rvs(size = 1)) # stupid appending to make it slower
if i % 10000 == 0:
print 'x0 = %s, i = %s' % (x0, i)
return sp.array(x)
def testfuncParallel(fargs):
return testfunc(*fargs)
# Define Number of tasks.
nTasks = 4
N = 100000
if __name__ == '__main__':
"""
Try number 1. Using multiprocessing.Pool together with Pool.map_async
"""
pool = mp.Pool(processes = nTasks) # I have 12 threads (six cores) available so I am suprised that it does not get access to nTasks = 4 amount of workers
# Define tasks:
tasks = [(x, n) for x, n in enumerate(nTasks*[N])] # nTasks different tasks
# Compute parallel: async - asynchronically, i.e. not necessary in order.
result = pool.map_async(testfuncParallel, tasks)
pool.close() # These are needed if map_async is used
pool.join()
# Get results:
sim = sp.zeros((N, nTasks))
for nn, res in enumerate(result.get()):
sim[:, nn] = res
pylab.figure()
for i in xrange(nTasks):
pylab.subplot(nTasks,1, i + 1)
pylab.plot(sim[:, i])
pylab.show()
提前致谢。
此致 Matias的
答案 0 :(得分:4)
我没有第一个问题的解决方案。事实上,我可以在我的64位Ubuntu盒子上使用Enthought的Python 2.7.1 [EPD 7.0-2(64位)]重复运行你的代码。 编辑:事实证明问题是由您的IDE(Wingware)引起的。显而易见的解决方法是从IDE外部运行脚本。
关于第二个问题,所发生的是在Unix上,每个工作进程都从父进程继承随机数生成器的相同状态。这就是他们生成相同的伪随机序列的原因。要解决这个问题,您只需在scipy.random.seed
顶部调用testfunc
:
def testfunc(x0, N):
sp.random.seed()
print 'working with x0 = %s' % x0
...
答案 1 :(得分:1)
更新:原来这与matplotlib或后端无关,而是与一般的多处理相关的错误。我们已经为Wing 4.0.4+修复了这个问题。解决方法不是在子流程中执行的代码中设置断点。
似乎是Wing IDE的matplotlib支持Tkinter后端与多处理交互严重。当我尝试这个例子时,它崩溃了TCL / Tk代码。我怀疑在Windows上工作的人使用的是另一个matplotlib后端。
在“扩展”选项卡下的“项目属性”中关闭“matplotlib事件循环支持”似乎可以解决它。
或者,当打开“matplotlib事件循环支持”时,添加以下内容似乎可以解决这个问题。
导入matplotlib matplotlib.use( 'WXAgg')
只有拥有WXAgg后端才能使用此功能。 Wing IDE支持的其他后端(即使调试过程暂停,图表仍保持交互状态)是GTKAgg和Qt4Agg,但我还没有尝试过。
我会看看能否找到并修复错误。我怀疑我们需要在进程ID更改时禁用事件循环支持。感谢您报告此事。