Хотя потоки, безусловно, являются решением этой проблемы (при условии правильной обработки общих данных), вы можете в качестве альтернативы запустить цикл while:
import time
import shlex
from subprocess import *
#list of commands
commands = ['sleep 5', 'ls -l', 'sleep 3', 'uptime', 'find /usr']
times = {}
running = {}
#executing each command in the list
for command in commands:
start_time = time.time()
cmd = shlex.split(command)
times[command] = time.time()
running[command] = Popen(cmd,
# no shell=True, shlex already did the split
stdout=PIPE, stderr=PIPE)
while len(running):
finished = set()
for cmd, proc in running.items():
if proc.poll() is not None:
times[cmd] = time.time() - times[cmd]
finished.add(cmd)
else:
proc.communicate() # drain the pipe
for cmd in finished:
del running[cmd]
print(times)
Обратите внимание, что он не будет блокироваться (в отличие от его многопоточности).альтернатива), так что это может в конечном итоге съесть ваш процессор.Чтобы уменьшить нагрузку, вы можете добавить вызов к time.sleep
в конце цикла, делая результаты немного неточными.
Редактировать: так как вы использовали каналы в примере, я предполагаю, что вы хотите использоватьвывод (некоторых) команд для некоторой значимой обработки.Независимо от того, хотите вы этого или нет, если вы не выполните proc.communicate
, вы закончите заполнять свою трубу, блокируя процесс.Кроме того, вы можете, конечно, перенаправить вывод (в какой-нибудь файл или / dev / null).Связь с процессом может также изменить результаты, как и обработка:)