如何在Python中使用多级并行化?

时间:2017-08-15 23:51:56

标签: python multiprocessing

场景: 主进程读取一些配置文件并生成3个进程--A,B和C.这些进程中的每一个都读取自己的配置文件并生成多个进程 - A1,A2,A3,B1,B2,C1,C2,C3,C4和C5。 (进程A产生Ax等)。

现在,进程A需要等待A1,A2和A3,然后做一些工作;进程B需要等待B1和B2,依此类推。主进程需要等待所有3个进程(A,B和C)完成,并完成其他一些任务。

建议的方法是什么?从本质上讲,这是一个产生一些孩子的东西,让他们并行运行并等待所有孩子完成"多层次的问题。

我尝试过多处理,但它仅适用于 main

我已经尝试过os.fork(),但无法让子进程退出。 sys.exit(n)或os._exit(n)创建僵尸进程和父进程 孩子退出时无法检测到(如何退出)?

谢谢您的提示。

def level2 (letterWithNumber):
    # do something with letter and number
    sys.exit(0)

def level1 (letter, conFileName):
    plist = anotherListFromConfigFile(conFileName)   # returns [A1, A2, A3] for A, etc.
    bList = array('i', [])
    bCount = 0
    foreach key in plist:
        pid = os.fork()
        if pid == 0:
            level2 (key)
        else:
            bList.append(pid)
            bCount += 1

    while True:
        count = 0
        for p in blist
            if waitpid(p,0):    # child is active
                count += 1
        if count == 0:
            break
        else:
            time.sleep(10)
    print (bCount, "jobs completed for task", letter
    sys.exit(0)

# main

dict = listFromConfigFile() # contains {A: a.conf, B: b.conf, C: c.conf}
alist = array('i', [])
ccount = 0
foreach key in dict:
    pid = os.fork()
    if pid == 0:
        level1(key, dict[key])
    else:
        alist.append(pid)
        ccount += 1

while True:
    count = 0
    for p in alist
        if waitpid(p,0):    # child is active
            count += 1
    if count == 0:
        break
    else
        time.sleep(10)

print (ccount, "top level tasks completed")
sys.exit(0)

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解你的观点。但是,如果您只是希望您的流程等待其他流程,则可以使用process.join()

例如:

from multiprocessing import Process
def time_consume():
    import time
    for i in range(10):
        print(i)
        time.sleep(1)

process = Process(target=time_consume)
process.start()
process.join()
print("process finished.")

实际上,你的问题并不像你想象的那么复杂,至少在我看来是这样。

您可以在主流程和join()中创建三个一级流程,在每个一级流程中,您还可以创建三个二级流程,然后在每个一级流程中调用join()等待2级流程。

它可能如下:

def level_two():
    #do_something

def level_one():
    level_two_processes = [Process(target=level_two), Process(target=level_two)]
    for process in level_two_processes:
        process.start()
    #do_something
    for process in level_two_processes:
        process.join()

def main():
    level_one_processes = [Process(target=level_one), Process(target=level_one)]
    for process in level_one_processes:
        process.start()
    #do_something
    for process in level_one_processes:
        process.join()