Я новичок в модуле подпроцессов python, в настоящее время моя реализация не обрабатывается многократно.
import subprocess,shlex
def forcedParsing(fname):
cmd = 'strings "%s"' % (fname)
#print cmd
args= shlex.split(cmd)
try:
sp = subprocess.Popen( args, shell = False, stdout = subprocess.PIPE, stderr = subprocess.PIPE )
out, err = sp.communicate()
except OSError:
print "Error no %s Message %s" % (OSError.errno,OSError.message)
pass
if sp.returncode== 0:
#print "Processed %s" %fname
return out
res=[]
for f in file_list: res.append(forcedParsing(f))
мои вопросы:
Является ли sp.communicate хорошим способом? следует ли использовать опрос?
Если я использую опрос, мне нужен процесс сперва, который контролирует, если процесс закончен правильно?
Должен ли я форк в цикле for
?
О вопросе 2: форсирование в цикле for будет в основном ускорять работу, если script предполагается запустить в системе с несколькими ядрами/процессорами. Тем не менее, он будет потреблять больше памяти и будет усиливать IO. Там где-то будет приятное место, которое зависит от количества файлов в file_list
, но только бенчмаркинг на реалистичной целевой системе может рассказать вам, где он находится. Если вы найдете это число, вы можете добавить if len(file_list) > <your number>:
с дополнительным fork()
'ing [ Изменить:, а @tokland сказать через multiprocessing
, если он доступен в вашей версии Python (2.6+ )], который выбирает наиболее эффективную стратегию для каждой работы.
Читайте о профилировании Python здесь: http://docs.python.org/library/profile.html
Если вы работаете в Linux, вы также можете запустить time
: http://linuxmanpages.com/man1/time.1.php
1) subprocess.communicate() кажется правильным вариантом для того, что вы пытаетесь сделать. И вам не нужно опрашивать процессы, общаться() возвращается только после его завершения.
2) вы подразумеваете forking для паралеллизации работы? посмотрите multiprocessing (python >= 2.6). Разумеется, выполнение параллельных процессов с использованием подпроцесса возможно, но это довольно сложная работа, вы не можете просто вызвать функцию connect(), которая блокирует.
О вашем коде:
cmd = 'strings "%s"' % (fname)
args= shlex.split(cmd)
Почему бы не просто?
args = ["strings", fname]
Что касается этого уродливого шаблона:
res=[]
for f in file_list: res.append(forcedParsing(f))
По возможности следует использовать списки-постижения:
res = [forcedParsing(f) for f in file_list]
В документации по подпроцессу есть несколько предупреждений, в которых рекомендуется использовать communicate, чтобы избежать проблем с блокировкой процессов, поэтому было бы неплохо использовать это.