多进程:PyObject_Call中无错误的NULL结果

8 投票
1 回答
7789 浏览
提问于 2025-04-17 23:57

这里有一个示例程序,我使用了多进程。计算是通过 multiprocessing.Process 来完成的,结果则是通过 multiprocessing.Queue 来收集的。

#THIS PROGRAM RUNS WITH ~40Gb RAM. (you can reduce a,b,c for less RAM 
#but then it works for smaller values)
#PROBLEM OCCURS ONLY FOR HUGE DATA.   
from numpy import *
import multiprocessing as mp

a = arange(0, 3500, 5)
b = arange(0, 3500, 5)
c = arange(0, 3500, 5)  
a0 = 540. #random values
b0 = 26.
c0 = 826.
def rand_function(a, b, c, a0, b0, c0):
    Nloop = 100.
    def loop(Nloop, out):
        res_total = zeros((700, 700, 700), dtype = 'float') 
        n = 1
        while n <= Nloop:
            rad = sqrt((a-a0)**2 + (b-b0)**2 + (c-c0)**2)
            res_total += rad
            n +=1 
        out.put(res_total)
    out = mp.Queue() 
    jobs = []
    Nprocs = mp.cpu_count()
    print "No. of processors : ", Nprocs
    for i in range(Nprocs):
        p = mp.Process(target = loop, args=(Nloop/Nprocs, out)) 
        jobs.append(p)
        p.start()

    final_result = zeros((700, 700, 700), dtype = 'float')

    for i in range(Nprocs):
        final_result = final_result + out.get()

    p.join()
test = rand_function(a,b,c,a0, b0, c0)

这里是错误信息:

Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/queues.py", line 266, in _feed
    send(obj)
SystemError: NULL result without error in PyObject_Call

我在这里看到这是一个bug。但我不太明白。 有没有人能告诉我,如何使用多进程来处理大量数据呢?

非常感谢!

1 个回答

4

你提到的错误报告说,multiprocessing模块无法将很大的参数传递给子进程。

原因是它需要对这些参数进行序列化(也就是把数据转换成一种可以存储和传输的格式),然后把这些序列化后的数据存放在内存中。

不过,你其实不需要把数组作为参数传递。

可能的原因有:

  • 把一个闭包 loop 作为目标传递
  • mp.Queue() 作为参数传递

请查看 http://stevenengelhardt.com/2013/01/16/python-multiprocessing-module-and-closures/,了解如何将你的闭包转换为一个类。

在将控制权交给multiprocessing之前,请先设置好完整的状态。

撰写回答