Python & Multiprocessing, разбивая наборы на подпроцессы - PullRequest
0 голосов
/ 24 ноября 2010

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

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

Вот код:

def build_feature_labels(self,strings,return_obj,l):
    feature_labels = set()
    for s in strings:
        feature_labels = feature_labels.union(s.get_feature_labels())
    print "method: ", len(feature_labels)
    l.acquire()
    return_obj.return_feature_labels(feature_labels)
    l.release()
    print "Thread Done"

def return_feature_labels(self,labs):
    self.feature_labels = self.feature_labels.union(labs)
    print "length self", len(self.feature_labels)
    print "length labs", len(labs)


current_pos = 0
lock = multiprocessing.Lock()

while current_pos < len(orig_strings):
    while len(multiprocessing.active_children()) > threads:
        print "WHILE: cpu count", str(multiprocessing.cpu_count())
            T.sleep(30)

    print "number of processes", str(len(multiprocessing.active_children()))
    proc = multiprocessing.Process(target=self.build_feature_labels,args=(orig_strings[current_pos:current_pos+self.MAX_ITEMS],self,lock))
    proc.start()
    current_pos = current_pos + self.MAX_ITEMS

    while len(multiprocessing.active_children()) > 0:
        T.sleep(3)


    print len(self.feature_labels)

Что странно, а) что self.feature_labels в главном процессе пуст, но когда он вызываетсяиз каждого подпроцесса есть элементы.Я думаю, что я использую неправильный подход (это то, как я делал это на Java!).Есть ли лучший подход?

Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 24 ноября 2010

Рассмотрите возможность использования пула рабочих: http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers. Это сделает большую часть работы за вас в стиле сокращения карт и вернет собранные результаты.

1 голос
/ 24 ноября 2010

Используйте multiprocessing.Pipe или Queue (или другой такой объект) для передачи данных между процессами.Используйте канал для передачи данных между двумя процессами и очередь для нескольких производителей и потребителей.

Наряду с официальной документацией, есть хорошие примеры, которые можно найти в учебнике по многопроцессорности Дуга Хеллмана В частности, в нем приведен пример использования multiprocessing.Pool для реализации операции типа mapreduce.Это может очень хорошо соответствовать вашим целям.

0 голосов
/ 25 ноября 2010

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

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