使用python和多处理进行压缩输出

时间:2011-10-25 13:51:02

标签: python numpy multiprocessing multicore pickle

所以我一直在用numpy和多处理编写数字的东西。它工作正常,但我收集结果时遇到问题。我已经按照以下方式完成了它,我将一个队列用于输入,一个用于输出。程序从输入队列中读取参数,对其进行处理,然后将结果放入输出队列。稍后在主要过程中,我从队列中读出来并腌制它。像这样:

def fun(inp,outp):
    while True:
        try:
            params = inp.get(block=False)
            results = runprocess(params)
            out.put(results,block=False)
        except Empty:
            break

稍后在主循环中执行以下操作:

for p in processes:
    p.start()
for p in processes:
    p.join()

while True:
     try:
          out = outp.get(block=False)
          a[i] = [out]
     except Empty:
          break

 fi = open(filename,"w")
 cPickle.dump(fi,a)
 fi.close()

但不知何故,两件事中总有一件事情发生了:要么腌制出来,要么流程挂起并保持运行,使用0%cpu(一开始它们达到100%,基本上是数字运算)。对我做错了什么的想法?

好的,所以我用Pool.map()重做了它。只是这样每个人都知道我是如何让它在这里工作的片段:

    ncpus = mp.cpu_count()
    out = dict()

    params = [(a,p) for p in np.arange(0.0,2.0,0.1) for a in np.arange(0.001,2.0,0.1)]

    pool = mp.Pool(processes=ncpus)
    results = pool.map(runm,params)

    for i in results:
            sigs = np.zeros((order,order))
            sigsmf = np.zeros((order,order))
            sigseq = np.zeros((order,order))
            xs = np.array([])
            freqs = np.array([])
            [(a,p),sigs[:,:],sigsmf[:,:],sigseq[:,:],xs,freqs] = i
            out[(a,p)] = [sigs[:,:],sigsmf[:,:],sigseq[:,:],xs,freqs]
            print a, p, sigs[0,0]

像魅力一样,更容易实现!

谢谢费迪南德!我不知道怎么做,但我想我们现在可以关闭这个问题了!

2 个答案:

答案 0 :(得分:2)

多数民众赞成因为你有阻止=假。当收集器尝试从队列中获取数据时,它不会立即找到它。因此引发了空异常并且它突然出现了循环

从输入列表中获取数据时,您可以指定block = False作为预填充列表。但是,输出队列是在运行时构建的。因此,当您尝试从中获取数据时,可能会因为输入过程需要更长时间才能处理它。

如果您知道输入队列的长度,那么您可以尝试无限期地阻止输出队列qet。如果没有,那么我建议您阻止超时。

答案 1 :(得分:2)

您需要至少在timeout次来电中添加get,然后移除block。在您当前的配置中,如果在调用get时没有可用的项目,您将获得Empty异常,从而退出循环。如果您依赖于不同的线程来填充该队列并且它没有及时填满它,它将过早地退出循环并产生空结果。同样,put可能因为队列已满而挂起,从而挂起您的程序。

所以,使用这样的东西:

params = inp.get(timeout=1)
out.put(timeout=1)