Python中的多处理意外返回None

2024-06-28 18:57:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图在python3.6(Anaconda发行版)中启动多处理。我已经对我的内部函数(数值积分)进行了大量的测试,所以我相信它是有效的。目前给我带来麻烦的是通过适当的范围,因为我得到一些“无”回报。在

import multiprocessing
from multiprocessing import Pool

def chunkwise(t, size=2):
    it = iter(t)
    return zip(*[it]*size)

def sint(tupl):
    print('arg = ',tupl)
    #lower = float(tupl[0])
    #upper = float(tupl[1])
    exit()
    #ans = scipy.integrate.quad(int2,lower,upper) 
    #return ans

n_CPUs = 6 

smin = float(10000)
smax = float(np.inf)
smax_spacing = float(2.5*10**12)
srange = np.linspace(smin,smax_spacing,n_CPUs)

srange = np.append(srange,np.inf)
print('length srange = ',len(srange))
filler=[]

for i in range(len(srange)):
    if i == 0:
        filler.append(float(srange[i]))
    elif srange[i] == srange[-1]:
        filler.append(float(srange[i]))
    else:
        filler.append(float(srange[i]))
        filler.append(float(srange[i]))
srange = np.array(filler)
srange = list(chunkwise(srange))

def main():
    pool = Pool(processes=n_CPUs)
    res1 = pool.map(sint,[(smin,float(smin*2)),  (float(smin*2),float(smin*3))])#srange)
    res = sum(res1)
    pool.close()
    pool.join()
    return res

if __name__ =="__main__":
    result = main()

我的一些调试过程可以在这里包含的代码中看到。现在,我只想查看传递给sint()函数的参数。当我打印结果时,我得到了结果

^{pr2}$

为什么会出现这些“无”?目前,它们的存在导致了代码的非并行版本中不存在的溢出/nan。有没有办法不让“无”出现?我尝试检查tupl、lower和upper中是否存在“None”,但Python似乎不想识别这些内容(不会打印我写的“None detected”消息)。在

任何帮助都将不胜感激!如果需要更多信息,请告诉我。在


Tags: returndefnpfloatupperlowerpoolfiller
1条回答
网友
1楼 · 发布于 2024-06-28 18:57:33

一个问题是,多处理会为您编写的所有内容启动一个单独的进程,它会完全创建一个单独的Python实例,因此您的代码实际上正在多次运行您在全局范围内放置的所有内容。运行您的代码将返回

>>> length srange =  7
>>> length srange =  7

对我来说是多次。您需要将其他代码移动到一个单独的函数中,或者在def main()内部调用它。但是,修复此问题仍然会导致none,这似乎是因为您实际上并没有在映射函数中返回任何东西,sminpool.map中。通常,您的结果是None个对象(sum也不能对none对象求和),但是这里有另一个问题。你的过程实际上并没有结束。在

这可能是因为您调用exit,没有返回或任何内容,甚至没有None。在

您不需要调用exit来结束映射函数,请查看multiprocessing以查看其中的示例。只需使用普通函数作为映射器,无需使用系统调用。在

尽管这不是您想要的,但这是一个简单的示例,用您的示例显示实际的多处理代码:

编辑:我没有意识到你发布的大部分内容都不是必需的,我鼓励你在发布问题时尽量少做可验证的示例,我缩小并更改了我原来发布的内容来进行实际的集成,我还鼓励你在提问和编写自己的代码时使用适当的命名约定,sint和{}是不例外的描述性名称。我在这里所做的是向您展示如何使用您提供的scipy集成实用程序在parralell中正确地执行集成。您可以将integrated_function替换为您自己函数的代码,它的工作原理应该是一样的

^{pr2}$

如果您的函数足够复杂,并且集成度足够大,那么多处理的开销应该足够低,以使它更快,请注意,用in线程打印出来会导致您不希望的速度减慢,所以在调试之外,我建议您不要打印。在

编辑:既然他们想做无限的整合,我也会在这里发表我的想法和代码的附录,而不是把它留在评论中。在

从技术上讲,即使积分范围是无限的,实际上也不是无限积分,近似无限积分的具体数值方法超出了这个问题的范围,但是由于^{}是一个使用Gaussian Quadrature进行积分的方法(因此得名“quad”),它解决了这个问题,并且可以以np.inf为界。不幸的是,我不知道如何保证这个边界的连续性能,它可能需要比所有其他集成更长的时间,或者它可能需要更少的时间,这意味着将工作分成相等的块变得更加困难。但是,您只需要更改积分范围的最后一个边界,以便在该范围中也包括无穷大。在

这种变化是这样的:

integration_ranges = [(i * integration_step, (i + 1) * integration_step) for i in range(integration_chunks)]
# we take the last element of the array, and all but the last element of the tuple, 
# and make a new tuple with np.inf as the last element
integration_ranges[-1] = integration_ranges[-1][:-1] + (np.inf,)

这样做之后,最后一个边界应该是无穷大的,所以您的总积分范围实际上是0->;inf,即使total_integration_range不是无穷大

相关问题 更多 >