Python如何使用多处理来返回不同的函数

Posted

技术标签:

【中文标题】Python如何使用多处理来返回不同的函数【英文标题】:Python how to use multiprocessing to different functions with return 【发布时间】:2021-11-27 23:23:26 【问题描述】:

我有几个 3 个小功能:

def getnpx(mt, age, interest):
    val = 1
    initval = 1
    for i in range(age, 55):
        val = val * mt[i]
        intval = val / (1 + interest) ** (i + 1 - age)
        initval = initval + intval
        
    return initval

def getnpx2(mt, age, interest):
    val = mt[age]
    initval = 1
    for i in range(age + 2, 55):
        val *= mt[i - 1]
        if mt[age]==0:
            intval =0
        else:
            intval = val / (1 + interest) ** (i - age - 1) / mt[age]
        initval = initval + intval
    return initval

def getnpxtocert(mt, age, maxvalue):
    val = mt[age]
    for i in range(age + 1, min(maxvalue, 7)):
        val = val * mt[i]
    return val

还有一个调用所有小函数的大函数:

def calcannfactprelim(pval, age, intrate, certper):
    npx = getnpx(pval, age + int(certper), intrate)
    npx2 = getnpx2(pval, age + int(certper), intrate)

    if certper == 0:
        index = 1
        index2 = pval[age + int(certper)]

    else:
        index = getnpxtocert(pval, age,
                             age + int(certper)) 
        index2 = getnpxtocert(pval, age,age + int(certper) + 1)

    return index*npx+index2*npx2

这些是要使用的变量:

pval = np.array([0.000291,0.00027,0.000257,0.000294,0.000325,0.00035,0.000371,0.000388,0.000402,0.000414,0.000425,0.000437,0.011016,0.012251,0.013657,0.015233,0.016979,0.018891,0.020967,0.023209,0.025644,0.028304,0.03122,0.034425,0.037948,0.041812,0.046037,0.050643,0.055651,0.06108,0.066948,0.073275,0.080076,0.08737,0.095169,0.103455,0.112208,0.121402,0.131017,0.14103,0.151422,0.162179,0.173279,0.184706,0.196946,0.210484,0.225806,0.243398,0.263745,0.287334,0.314649,0.346177,0.382403,0.423813,0.470893])
age=3
intrate=0.04
certper=1

常规功能测试结果:

start=time.time()
print(calcannfactprelim(pval, age, intrate, certper))
print(time.time()-start)

输出是:

0.0002941874880982305 #result
0.0                   #time

为了让这个函数更快,我使用python多重处理来并行运行它。

import multiprocessing

def calcannfactprelim_v(pval, age, intrate, certper):
    
    p1 = multiprocessing.Process(target=getnpx, args=(pval, age, intrate, certper,))
    p2 = multiprocessing.Process(target=getnpx2, args=(pval, age, intrate, certper,))

    # starting process 1
    p1.start()
    # starting process 2
    p2.start()

    # wait until process 1 is finished
    p1.join()
    # wait until process 2 is finished
    p2.join()

    # both processes finished
    if certper == 0:
        index = 1
        index2 = pval[age + int(certper)]

    else:
        index = getnpxtocert(pval, age,
                             age + int(certper)) 
        index2 = getnpxtocert(pval, age,age + int(certper) + 1)


    return index*npx+index2*npx2

但是我不知道这种情况如何返回值,有哪位朋友可以帮忙完成代码并做个测试?

【问题讨论】:

使用multiprocessing.Process(),您需要为进程创建一个队列,以便将值返回给主进程。或者,您可以使用多进程池,这将为您做同样的事情。有一些简单的例子here 【参考方案1】:

在父进程中创建一个对象,比如说,

class ResultHolder():
     def __init__():
          result_a = None
          ………
          result_n = None

将此类作为参数传递给要在子进程中运行的函数,并让函数将结果写入,例如:

instance_of_result_holder.result_a = the_function_output

我相信您也可以通过传递字典或列表来做到这一点。长话短说,对象以类似于传递引用的方式传递,这意味着您可以将它们用作父进程和子进程的两个独立世界(上下文)之间的中介(即子进程可以改变定义的对象在父级中,您将后者作为参数传递给相应的函数)。

池和队列是实现这一目标的另一种方式。

【讨论】:

【参考方案2】:

您需要一些渠道来返回数据。这是在多处理池中为您完成的。

def calcannfactprelim_v(pval, age, intrate, certper):
    with multiprocessing.pool(2) as pool:
        a1 = pool.apply_async(getnpx, (pval, age, intrate, certper,))
        a2 = pool.apply_async(getnpx2, (pval, age, intrate, certper,))
        result1 = a1.get()
        result2 = a2.get()

    # both processes finished
    if certper == 0:
        index = 1
        index2 = pval[age + int(certper)]

    else:
        index = getnpxtocert(pval, age,
                             age + int(certper)) 
        index2 = getnpxtocert(pval, age,age + int(certper) + 1)
    return index*npx+index2*npx2

您甚至可以创建一个 1 池并在主程序中执行其中一个调用。假设一个返回一个大值,另一个返回一个小值。在你的 main 中做大的,这样从进程中将值返回给父进程的开销会更少。

【讨论】:

以上是关于Python如何使用多处理来返回不同的函数的主要内容,如果未能解决你的问题,请参考以下文章

Python多处理:如何创建x个进程并返回返回值

如何结合python多处理和管道技术?

Python多处理 - 从3个不同的函数返回值[重复]

从多处理池函数返回值

python的线程如何返回值?

如何从 python 中的多处理中获取函数输出?