Мультипроцессный подпроцесс - PullRequest
1 голос
/ 20 августа 2010

Я новичок в подпроцессном модуле 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))

мои вопросы:

  1. Является ли sp.communicate хорошим вариантом? я должен использовать опрос?

    если я использую опрос, мне нужен отдельный процесс, который отслеживает, правильно ли завершен процесс?

  2. я должен раскошелиться на петлю for?

Ответы [ 3 ]

3 голосов
/ 20 августа 2010

1) subprocess.communicate () кажется правильным вариантом для того, что вы пытаетесь сделать.И вам не нужно опрашивать процесс, общаться () возвращает только после его завершения.

2) вы имеете в виду разветвление, чтобы парализовать работу?взгляните на многопроцессорность (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]
2 голосов
/ 20 августа 2010

О вопросе 2: разветвление в цикле for в основном ускорит процесс, если предполагается, что скрипт должен работать в системе с несколькими ядрами / процессорами. Тем не менее, он потребляет больше памяти и сильнее нагружает IO. Где-то будет приятное место, которое зависит от количества файлов в file_list, но только сравнительный анализ на реалистичной целевой системе может подсказать, где она находится. Если вы найдете это число, вы можете добавить if len(file_list) > <your number>: с необязательным fork() 'ing [ Edit: , скорее всего, как @tokland скажет через multiprocessing, если оно доступно в вашей версии Python (2.6+) ], которая выбирает наиболее эффективную стратегию для каждой работы.

Читайте о профилировании Python здесь: http://docs.python.org/library/profile.html

Если вы работаете в Linux, вы также можете запустить time: http://linuxmanpages.com/man1/time.1.php

1 голос
/ 20 августа 2010

В документации есть несколько предупреждений , в которых рекомендуется использовать общаться , чтобы избежать проблем с блокировкой процессов, поэтому было бы неплохо использовать это.

...