Многопроцессорный подпроцесс

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


person Phyo Arkar Lwin    schedule 20.08.2010    source источник


Ответы (3)


О вопросе 2: разветвление цикла for в основном ускорит работу, если сценарий должен работать в системе с несколькими ядрами/процессорами. Однако он будет потреблять больше памяти и будет сильнее нагружать ввод-вывод. Где-то будет выигрышное место, которое зависит от количества файлов в 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

person Jacob Oscarson    schedule 20.08.2010
comment
Хорошо, я могу ограничить количество вилок coz. Да, я работаю в Linux, и список файлов может достигать 10 000 +, поэтому, скажем, 10 разветвлений одновременно должны быть в порядке (рабочий сервер будет 8-ядерным с 16 ГБ оперативной памяти DDR3). - person Phyo Arkar Lwin; 21.08.2010

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

2) вы имеете в виду разветвление для распараллеливания работы? взгляните на многопроцессорность (python >= 2.6). Запуск параллельных процессов с использованием подпроцесса, конечно, возможен, но это довольно трудоемкая работа, вы не можете просто вызвать коммуникацию(), которая блокирует.

О вашем коде:

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]
person tokland    schedule 20.08.2010
comment
Тоже хороший ответ, да, я хочу использовать многопроцессорность, но текущая стабильная версия Debian имеет только версию 2.5.x, что отстой. Позже я могу перейти на gentoo/sabayon. Большое спасибо за исправление моего синтаксиса, это всего лишь пример кода, на самом деле внутри есть несколько условий, поэтому понимание списка будет невозможно. , это плохая новость. ТАК используя вместо этого опрос? мне просто нужен вывод при выходе из программы, а не все время.. - person Phyo Arkar Lwin; 21.08.2010
comment
Вы можете попробовать поддержку многопроцессорности: code.google.com/p/python-multiprocessing. - person tokland; 21.08.2010

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

person Mark Byers    schedule 20.08.2010
comment
Исправление, он не блокируется в многопроцессорном модуле (форк тоже будет работать!) - person Phyo Arkar Lwin; 19.11.2010