如何在核心空闲时添加进程,在python中执行批量计算?

时间:2018-04-10 15:37:14

标签: python python-2.7 parallel-processing multiprocessing

Bash具有"等待-n"这可以以相对简单的方式用于停止后续执行子进程,直到一定数量的处理器核可用。例如。我可以做到以下几点,

for IJOB in IJOBRANGE;
do

    ./func.x ${IJOB}

    # checking the number of background processes
    # and halting the execution accordingly

    bground=( $(jobs -p) );

    if (( ${#bground[@]} >= CORES )); then
        wait -n
    fi

done || exit 1

此代码段可批量执行任意C进程" func.x"使用不同的参数并始终维护子进程的固定数量的并行实例,设置为值" CORES"。

我想知道是否可以使用python脚本完成类似的操作 python子进程(或函数)。目前,我定义了一个python函数,设置了一个一维参数数组,并使用python多处理模块中的Pool例程来并行计算参数数组上的函数。池函数执行我的函数评估的设定数量(在以下示例中为CPU CORES)并等待,直到生成的进程的所有实例都已结束,然后才转移到下一批。

import multiprocessing as mp

def func(x):

    # some computation with x

def main(j):

    # setting the parameter array
    xarray = range(j)

    pool = mp.Pool()
    pool.map(func,xarray)

我想知道是否可以修改此代码段以便始终执行我的子例程的固定数量的并行计算,即,只要其中一个子进程完成就添加另一个进程。所有" func"这里的过程应该是独立的,执行顺序也无关紧要。我是python方式的新手,拥有一些有用的观点真的很棒。

1 个答案:

答案 0 :(得分:1)

根据我们在评论中的讨论,这里有一些改编自您的测试代码,显示Pool不会等待所有并行任务完成,然后再为可用的工作人员分配新的任务:

import multiprocessing as mp
from time import sleep, time


def func(x):
    """sleeps for x seconds"""
    name = mp.current_process().name
    print("{} {}: sleep {}".format(time(), name, x))
    sleep(x)
    print("{} {}: done sleeping".format(time(), name))


def main():

    # A pool of two processes, for the sake of simplicity
    pool = mp.Pool(processes=2)
    # Here's how that works out visually:
    #
    #    0s        1s       2s        3s
    # P1 [sleep(1)][     sleep(2)     ]
    # P2 [     sleep(2)     ][sleep(1)]
    sleeps = [1, 2, 2, 1]
    pool.map(func, sleeps)


if __name__ == "__main__":
    main()

运行此代码(为简化起见,简化了时间戳):

$ python3 mp.py 
0s: ForkPoolWorker-1: sleep 1
0s: ForkPoolWorker-2: sleep 2
1s: ForkPoolWorker-1: done sleeping
1s: ForkPoolWorker-1: sleep 2
2s: ForkPoolWorker-2: done sleeping
2s: ForkPoolWorker-2: sleep 1
3s: ForkPoolWorker-1: done sleeping
3s: ForkPoolWorker-2: done sleeping

我们可以看到第一个进程在开始第二个任务之前没有等待第二个进程完成第一个任务。

所以我想这应该回答你提出的观点,希望我能清楚地理解你。