2017-05-05 54 views
0

我试图在shell上使用python进行自动化手动模拟测试。我有一个父目录中的子文件夹我的数据设置像这样:目录中的多个子进程

/vol/parent/child1 
/vol/parent/child2 
/vol/parent/child3 
... 
/vol/parent/childn 

我有单独的脚本,它运行在每个子目录的测试工作(这也是一个python程序)。这些脚本使用subprocess.Popen和示例如下:

folder_list = next(os.walk(parent))[1] 

for child in folder_list: 
f = open("/vol/testjob1/nohup.out", "w") 
p = subprocess.Popen([<...testjob1.py...test parameters>], cwd = '/vol01/testjob1/', stdout=f) 

这将运行在每个子文件夹的工作,每个线程1点的工作。

通常,我会等待所有n个作业完成,然后运行我的下一个测试(例如testjob2),这又是一个类似的子过程类型程序。

我试图将所有这些子进程测试脚本合并到一个主脚本中。主要目标是一个作业在一个线程上完成的时刻,下一个子进程在该线程上开始。我在最后尝试追加p.wait(),但这意味着它将等待每个线程在启动下一个线程之前完成(这会杀死并行运行这些作业的目的)。

如何使用subprocess.popen,p.wait()的组合和for循环,以确保1个工序陆续开始,像这样:

(child1)| thread1: Subprocess1 (done)--> start subprocess2 (done)--> start subprocess3... 
(child2)| thread2: Subprocess1 (done)--> start subprocess2 (done)--> start subprocess3... 
... 
(childn)| threadn: Subprocess1 (done)--> start subprocess2 (done)--> start subprocess3... 
+0

我不明白。你是否真的创建线程?因为如果你这样做,你可以在每个线程中循环和等待(这就是我要做的,我甚至会在你的情况下使用'check_output'而不是'Popen'(顺便说一句,因为你的循环中打开了'f'',每个新的结果覆盖前一个) –

+2

如果你创建线程,我们没有看到代码,你是在用线程混合'Popen'吗?因为'Popen'创建_processes_。 –

回答

0

现在你有一个线程启动工作为所有文件夹。您需要将其反转为每个文件夹启动其所有作业的一个线程。使用ThreadPool很容易,它将为您处理线程启动/排队操作。

import multiprocessing.pool 

jobs = [<...testjob1.py...test parameters>, 
    <...testjob2.py...test parameters>, 
    <...testjob3.py...test parameters>] 

def worker(folder, jobs, outfp): 
    for job in jobs: 
     subprocess.call(job, cwd=folder, stdout=outfp)) 

folder_list = next(os.walk(parent))[1] 
pool = multiprocessing.pool.ThreadPool(len(folder_list)) 
for result in pool.map(worker, ((folder, jobs, f) for folder in folder_list))): 
    pass 
pool.close() 
pool.join() 

如果其好有在同一时间同一文件夹中运行多个作业,你可以安排他们更细粒度的。假设一个目录中的作业本质上比其他目录长。在上面的例子中,你会等待“高调”。在这个例子中,工作会更均匀地分散开来。

import multiprocessing.pool 

jobs = [<...testjob1.py...test parameters>, 
    <...testjob2.py...test parameters>, 
    <...testjob3.py...test parameters>] 

def worker(folder, jobs, outfp): 
    subprocess.call(job, cwd=folder, stdout=outfp)) 

folder_list = next(os.walk(parent))[1] 
pool = multiprocessing.pool.ThreadPool(len(folder_list)) 
for result in pool.map(worker, ((folder, job, f) 
     for folder , job in itertools.product(folder_list, jobs))), 
     chunksize=1): 
    pass 
pool.close() 
pool.join()