我正在使用Python编写一个脚本,以这种方式打开多个子进程:
for file in os.listdir(FOLDER):
subprocess.Popen(([myprocess]))
现在这个进程可以并行运行10-20个,每个进程都会在控制台中输出一个字符串行。我想要做的是将这些输出(无论以哪种顺序)附加到数组,并且当所有进程完成后,继续执行其他操作的脚本。
我不知道如何将每个输出附加到数组中,我想要检查是否所有子进程都已完成,我可以这样做:
outputs = []
k = len(os.listdir(FOLDER))
if len(outputs) == k
print "All processes are done!"
UPDATE!这段代码现在似乎有用了:
pids=set()
outputs = []
for file in os.listdir(FOLDER):
p = subprocess.Popen(([args]), stdout=subprocess.PIPE)
pids.add(p.pid)
while pids:
pid,retval=os.wait()
output = p.stdout.read()
outputs.append(output)
print('{p} finished'.format(p=pid))
pids.remove(pid)
print "Done!"
print outputs
问题是outputs
看起来像这样
>> Done!
>> ['OUTPUT1', '', '', '', '', '', '', '', '', '']
只填充第一个值,其他值为空,为什么?
答案 0 :(得分:2)
我想要做的是将这些输出(无论以哪种顺序)附加到数组,并且当所有进程完成后,继续执行其他操作的脚本。
#!/usr/bin/env python
import os
from subprocess import Popen, PIPE
# start processes (run in parallel)
processes = [Popen(['command', os.path.join(FOLDER, filename)], stdout=PIPE)
for filename in os.listdir(FOLDER)]
# collect output
lines = [p.communicate()[0] for p in processes]
要限制并发进程数,可以使用线程池:
#!/usr/bin/env python
import os
from multiprocessing.dummy import Pool, Lock
from subprocess import Popen, PIPE
def run(filename, lock=Lock()):
with lock: # avoid various multithreading bugs related to subprocess
p = Popen(['command', os.path.join(FOLDER, filename)], stdout=PIPE)
return p.communicate()[0]
# no more than 20 concurrent calls
lines = Pool(20).map(run, os.listdir(FOLDER))
后一个代码示例也可以同时读取多个子进程,而前者基本上在相应的stdout OS管道缓冲区已满后序列化执行。
答案 1 :(得分:0)
您可以等到所有人完成工作,然后汇总他们的标准输出。要了解它是如何完成的,请参阅this answer,其中详细介绍了实施。
如果你需要异步执行,你应该为这个作业生成一个新线程,并在那个线程中等待。
如果您需要实时获得有关结果的通知,您可以单独为每个进程生成一个线程,在每个线程中等待它们,然后在它们完成后更新您的列表。
要阅读流程的输出,您可以使用subprocess.PIPE
之类的#!/usr/bin/python2
import os
import random
import subprocess
outputs = []
processes = []
for i in range(4):
args = ['bash', '-c', 'sleep ' + str(random.randint(0, 3)) + '; whoami']
p = subprocess.Popen(args, stdout=subprocess.PIPE)
processes.append(p)
while processes:
p = processes[0]
p.wait()
output = p.stdout.read()
outputs.append(output)
print('{p} finished'.format(p=p.pid))
os.sys.stdout.flush()
processes.remove(p)
print outputs
。
编辑这是一个适合我的完整示例:
mail()