Мультипроцессный подпроцесс

1

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

Теги:
multithreading
process
subprocess
fork

3 ответа

2
Лучший ответ

О вопросе 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

  • 0
    Хорошо, я могу ограничить количество вилок ofcoz. Да. Я нахожусь на Linux, и список файлов может идти более 10k +, скажем, около 10 вилок одновременно должно быть в порядке (рабочий сервер будет 8 ядер с до 16 ГБ оперативной памяти DDR3).
3

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]
  • 0
    Хороший ответ тоже, да, я хочу использовать многопроцессорность, но в текущей стабильной версии Debian есть только 2.5.x, что отстой. Я могу перейти на gentoo / sabayon позже. Большое спасибо за исправление моего синтаксиса, это всего лишь пример кода, в действительности есть несколько условных операторов внутри, поэтому списки не будут возможны. Если я выполню разборку в цикле, subprocess.communicate просто заблокирует, верно? Это плохие новости. Так что вместо этого использовать опрос? мне просто нужен вывод при выходе из программы, а не все время ..
  • 2
    Вы можете попробовать многопроцессорный бэкпорт : code.google.com/p/python-multiprocessing .
1

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

  • 0
    ну subprocess.communicate ждет .. так что разветвление будет заблокировано ..
  • 0
    Исправление: он не блокируется в многопроцессорном модуле (форк тоже будет работать!)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню