2013-12-09 5 views
0

Итак, у меня есть два сценария python. Первый - это синтаксический анализатор, который сканирует тысячи файлов, а второй - планировщик, который разворачивает сканирование сотен отдельных каталогов. Моя проблема заключается в следующем:Python: принудительное число процессов в многопроцессорном пуле

У меня ограниченное количество дисковых ресурсов, и каждое сканирование использует около 1 ГБ локального хранилища sqlite3. Мне нужно ограничить количество процессов, так что пока максимальное количество процессов будет запущено, я не получу ошибку ввода-вывода на диске, которую я получаю.

Я пробовал использовать следующий код, чтобы развернуть сканирование и сохранить процессы в 8, но когда я смотрю в своем временном каталоге (где хранятся временные локальные файлы), в нем имеется значительно больше 8 файлов, показывающих мое Я не ограничиваю процессы должным образом (я использую os.remove, чтобы избавиться от временных файлов после завершения сканирования).

Это мой метод выполнения сканирования, что только Сервер порождает покинуть процесс с хорошо отформатированной командой

def execute_scan(cmd): 
    try: 
     log("Executing "+ str(cmd)) 
     subprocess.call(cmd, shell=False) 
    except Exception as e: 
     log(e) 
     log(cmd) 

Это в моем основном методе, где getCommand (OBJ) преобразует данные в объекте в массив команд ,

tasks = [getCommand(obj) for obj in scanQueue if getCommand(obj) is not None] 
multiprocessing.Pool(NUM_PROCS).map(execute_scan, tasks) 

Я мог бы использовать любой совет, который я могу получить, потому что я имею дело с большим количеством данных, и мой диск не так уж велик.

Большое спасибо!

+1

Повторюсь еще раз: [параллельные задачи, связанные с привязкой ввода-вывода, приводят к худшему времени выполнения, чем выполнение задач в одном потоке (или процессе)] (http://stackoverflow.com/a/20421535/1595865) , Использование нескольких потоков или процессов полезно только в том случае, если вы имеете дело с задачей, связанной с процессором (и даже тогда, а не каждый раз). – goncalopp

+0

. Вы не указали какой-либо код, который удаляет временные файлы, но это, вероятно, проблема. Глядя на временные файлы, чтобы косвенно определить, сколько процессов запущено, - странно ;-) Используйте инструмент ОС, чтобы подсчитать количество процессов напрямую. 'Pool (NUM_PROCS)' создает * точно * 'NUM_PROCS' процессы - не больше и не меньше. –

+0

@TimPeters Как я упоминал в описании, я удаляю временные файлы с помощью os.remove (path), и эта часть работает нормально. – onetwopunch

ответ

0

Хотя я мог бы, вероятно, использовали мультипроцессирование в данном заявлении, оказывается, что из-за ввода-вывода в базу данных sqlite3 был узким, многопроцессорная фактически замедляя его как предсказал гонкалопп.

0

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

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

Вот краткое руководство об использовании gevent.pool.Pool

Смежные вопросы