Распараллелить мою программу на Python - PullRequest
3 голосов
/ 30 марта 2011

У меня есть программа на python, которая читает строку из входного файла, выполняет некоторые манипуляции и записывает ее в выходной файл.У меня есть четырехъядерный компьютер, и я хочу использовать их все.Я думаю, что есть две альтернативы для этого:

  1. Создание n нескольких процессов Python, каждый из которых обрабатывает общее количество записей / n
  2. Создание n потоков в одном процессе Python для каждого вводазапись и каждый поток обрабатывает запись.
  3. Создание пула из n потоков в одном процессе Python, каждый из которых выполняет входную запись.

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

Ответы [ 3 ]

4 голосов
/ 30 марта 2011

Эталонная реализация интерпретатора Python (CPython) содержит печально известную «Глобальную блокировку интерпретатора» (GIL) , эффективно позволяющую только одному потоку одновременно выполнять код Python. В результате многопоточность очень ограничена в Python - если только вы не выполняете тяжелую работу в расширениях C, которые выпускают GIL.

Самый простой способ преодолеть это ограничение - использовать модуль multiprocessing. Он имеет API, аналогичный threading, и довольно прост в использовании. В вашем случае вы могли бы использовать это следующим образом (при условии, что манипулирование является сложной частью):

import multiprocessing

def process_line(line):
    # This function is executed in your worker processes.  Manipulate the
    # line and return the results.
    return manipulate(line)

if __name__ == '__main__':
    with open('input.txt') as fin, open('output.txt', 'w') as fout:
        # This creates a pool of N worker processes, where N is the number
        # of CPUs in your machine.
        pool = multiprocessing.Pool()

        # Let the workers do the manipulation and write the results to
        # the output file:
        for manipulated_line in pool.imap(process_line, fin):
            fout.write(manipulated_line)
0 голосов
/ 30 марта 2011

Номер один правильный ответ.

Прежде всего, проще создавать и управлять несколькими процессами, чем несколькими потоками. Вы можете использовать модуль multiprocessing или что-то вроде pyro, чтобы позаботиться о деталях. Во-вторых, многопоточность должна иметь дело с глобальной блокировкой интерпретатора Python, что делает ее более сложной, даже если вы являетесь экспертом в многопоточности с Java или C #. И самое главное, производительность на многоядерных машинах предсказать сложнее, чем вы думаете. Если вы не реализовали и не определили два различных способа сделать что-то, ваша интуиция относительно того, какой путь наиболее быстрый, вероятно, неверна.

Кстати, если вы действительно являетесь экспертом в области потоков Java или C #, то вам, вероятно, следует вместо этого использовать потоки, но вместо CPython использовать Jython или IronPython.

0 голосов
/ 30 марта 2011

Одновременное чтение одного и того же файла из нескольких процессов довольно сложно. Можно ли предварительно разбить файл?

Хотя у Python есть GIL, у Jython и IronPython нет этого ограничения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...