通过多处理检测多个子进程的终止

时间:2019-02-08 10:02:50

标签: python multiprocessing

#!/usr/bin/python
import os

from os import getpid

import multiprocessing


build="613719"
file1=open('/auto/home/venkam11/python/install-script/build-ddr-file.txt', 'r')

def installation(model,ddr,build):

    cli = "/auto/tools/qa/shared/qa-branch/util/install.pl -durham -restart -silentinstall -model %s -branch 6.2A %s %s"  %(model, ddr, build)

    print cli
    os.popen2(cli)
    print "installation has started on %s \n" %ddr

如果名称 =='主要':

pid=getpid()

print("parent process id :{}".format(getpid()))

for ddr in file1:
    print ddr.rstrip()
    if 'dd4500' in ddr:
        print "dd4500"
        model = "dd4500"
    elif ('apollo' or 'apolloplus') in ddr:
        print "dd9500"
        model = "dd9500"
    elif 'dd2500' in ddr:
        print "dd2500"
        model = "dd2500"
    elif 'dd7200' in ddr:
        print "dd7200"
        model = "dd7200"
    elif 'jupiter' in ddr:
        print "dd9800"
        model = "dd9800"
    ddr = ddr.rstrip()
    ins=multiprocessing.Process(target=installation, args=(model,ddr,build))
    ins.start()

基本上,我想读取具有计算机名称的文件,并使用多处理程序,因此我想在已读取的计算机上安装操作系统。

上面是我的代码,当我运行时,它立即开始在所有计算机上安装,并且主程序终止。

但是我希望主程序不终止,它必须等到子进程完成作业,然后返回输出,说明子进程作业已完成。

安装make需要1个小时或2个小时的任何时间,但我希望收到一条消息,说所有处理作业都已完成。

有人可以在这里帮忙吗?

2 个答案:

答案 0 :(得分:1)

填充进程列表,并使用join()将其与父进程一起加入,然后打印消息。这样,父母可以等到孩子完成任务后再执行下面的代码。

同一代码应如下所示:

#!/usr/bin/python
import os
import multiprocessing
import subprocess
import time
import sys

from os import getpid

file1 = open('/auto/home/venkam11/python/install-script/build-ddr-file.txt', 'w+')
print ("enter the ddr names one by one in each line and press ctrl-d twice")
userInput = sys.stdin.readlines()
file1.writelines(userInput)
file1.close()
build = input("\nenter the build number : \n")
branch = raw_input("enter the branch name  : " )
file1 = open('/auto/home/venkam11/python/install-script/build-ddr-file.txt', 'r')

def installation(model, branch, ddr, build, shared_dict):
        cli = "/auto/tools/qa/shared/qa-branch/util/install.pl -durham -restart -silentinstall -model %s -branch %s %s %s"  %(model, branch, ddr, build)
        print cli
        print "installation has started on %s \n" % ddr
        time.sleep(20)
        try:
            subprocess.check_call(cli, shell=True)
            shared_dict[ddr] = True
        except subprocess.CalledProcessError:
            shared_dict[ddr] = False

if __name__ == '__main__':
    #pid=getpid()
    #print("parent process id : {}".format(getpid()))
    processes = []
    manager = multiprocessing.Manager()
    shared_dict = manager.dict()
    for ddr in file1:
        print ddr.rstrip()
        if 'dd4500' in ddr:
            print "dd4500"
            model = "dd4500"
        elif ('apollo' or 'apolloplus') in ddr:
            print "dd9500"
            model = "dd9500"
        elif 'dd2500' in ddr:
            print "dd2500"
            model = "dd2500"
        elif 'dd7200' in ddr:
            print "dd7200"
            model = "dd7200"
        elif 'jupiter' in ddr:
            print "dd9800"
            model = "dd9800"

        ddr = ddr.rstrip()
        ins = multiprocessing.Process(target=installation, args=(model, branch, ddr, build, shared_dict))
        ins.start()
        processes.append(ins)

    for process in processes:
        process.join()

    print('All the installations are complete')
    print('Details: ')
    for ddr, success in shared_dict.items():
        if success:
            print('Installation on {} successful'.format(ddr))
        else:
            print('Installation on {} unsuccessful'.format(ddr))

答案 1 :(得分:0)

欢迎使用Stackoverflow。与线程非常相似,与子流程同步的最简单方法是join(),最通常是在创建线程/流程中进行。引入os.popen2模块时,不推荐使用subprocess调用,因为它没有提供对启动子进程的必要控制和通信程度。为此,您已经正确推断出可以使用multiprocessing模块。

使用multiprocessing解决问题的技术答案已在另一个答案以及this question中得到了很好的说明,它解释了调用实体如何与其子进程同步。通过将每个子流程存储在一个列表中来处理未知数量的子流程是非常允许的,例如,像这样

for p in my_processes:
    p.join()

一个更有用的答案可能是the subprocess module允许创建和监视其他进程,而没有multiprocessing的开销和复杂性,而public class Product { public string ProductCode { get; set; } public string ProductInfo { get; set; } } 具有用于进程间通信的高级功能,而您尚未(尚未)似乎需要。它的文档中有很多很好的示例,说明了如何修改旧的和/或不太合适的Python代码以使用新模块,因此值得一看。