2012-02-18 3 views
4

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

if __name__ == '__main__': 
    pool = Pool(processes=4) 
    for i, x in enumerate(data): 
     pool.apply_async(new_awesome_function, (i, x)) 
    pool.close() 
    pool.join() 

данных является список ([1,2,3,4,5]), и я пытаюсь взять список отправки каждого предмета выполняться с несколькими процессорами, но когда я завершаю свою рабочую команду в функцию и отправляю этот код, она ничего не делает (когда я вызываю эту функцию без кода выше, она отлично работает). Поэтому я думаю, что я использую многопроцессорную обработку неправильно (хотя я взял примеры с сайтов), любые предложения?

Обновление: Я заметил, что не могу даже вырваться из него, когда он зависает с помощью control-c .., который всегда работает, чтобы выйти из моих багги программ. Я посмотрел на python2.5 multiprocessing Pool и попытался следовать советам и добавил импорт внутри своего оператора if, но не повезло

Обновление2: Извините, только что понял, ответ на этот вопрос ниже, что команда работает, но это не кажется прекратить программу или позволить мне выйти из игры.

+0

Ваша проблема, вероятно, в 'my_awesome_function'. Я думаю, вам нужно показать нам эту функцию. –

+0

Я только что опубликовал код и ожидаемый результат (который работает до того, как я добавил многопроцессорность). – Lostsoul

+0

Его так странно, как правило, я получаю сообщение об ошибке, которое просто ничего не будет делать и зависает. Сначала он запускался, но не выходил (это был простой пример), но после того, как я поместил свой полный код в никуда, и он все равно не позволяет мне выйти. Я попытался отложить отладочные операторы печати, но ни один из них не вызвал (даже те, что были вне оператора if – Lostsoul

ответ

2

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

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

В окне отсутствует fork(), поэтому он перезапустит ваш скрипт. В вашем случае это будет очень плохо, потому что все это снова упадет. Вы можете предотвратить это, сбросивсь в бит if __name__ == '__main__':.

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

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

Но базы данных предназначены для хранения вещей. До тех пор, пока вы выполняете обработку, вы должны сделать это внутри своего кода перед удалением базы данных. Вы в основном используете базу данных a s set, и ваш код будет намного приятнее с использованием набора python. Если вам действительно нужно положить этот материал в базу данных, сделайте это в конце своей программы.

+0

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

+0

, кстати, я не использую окна, только Linux и Mac. Я попробую поставить инструкции связи внутри функции и увидеть, как она запускает программу. Кроме того, он работал до, но очень медленный, как один процесс (но ошибок в памяти не было), поэтому я пытаюсь использовать многопроцессор, так как каждый процесс независим. Я думал, что могу вызвать множество из них, чтобы ускорить процесс. – Lostsoul

+0

@ Lostsoul, база данных была неправильным решением проблем с памятью. Я предлагаю вам опубликовать версию до базы данных на codereview.stackexchange.com и попросить помочь уменьшить использование памяти. –

2

Ваш код, кажется, работает для меня:

from multiprocessing import Pool 
import time 

def new_awesome_function(a,b): 
    print(a,b, 'start') 
    time.sleep(1) 
    print(a,b, 'end') 

if __name__ == '__main__': 
    data = [1,2,3,4,5] 
    pool = Pool(processes=4) 
    for i, x in enumerate(data): 
     pool.apply_async(new_awesome_function, (i, x)) 
    pool.close() 
    pool.join() 

дал мне:

0 1 start 
1 2 start 
2 3 start 
3 4 start 
1 2 end 
0 1 end 
4 5 start 
2 3 end 
3 4 end 
4 5 end 

Что заставляет вас думать, что не работает?


Edit: Попробуйте запустить это и посмотрите на результат:

from multiprocessing import Pool 
import time 

def new_awesome_function(a,b): 
    print(a,b, 'start') 
    time.sleep(1) 
    print(a,b, 'end') 
    return a + b 

if __name__ == '__main__': 
    data = [1,2,3,4,5] 
    pool = Pool(processes=4) 
    results = [] 
     for i, x in enumerate(data): 
     r = pool.apply_async(new_awesome_function, (i, x)) 
     results.append((i,r)) 
    pool.close() 
    already = [] 
    while len(already) < len(data): 
     for i,r in results: 
      if r.ready() and i not in already: 
       already.append(i) 
       print(i, 'is ready!') 
    pool.join() 

Шахта:

0 1 start 
1 2 start 
2 3 start 
3 4 start 
0 1 end 
4 5 start 
1 2 end 
2 3 end 
0 is ready! 
3 4 end 
1 is ready! 
2 is ready! 
3 is ready! 
4 5 end 
4 is ready! 
+0

Я проверил вывод, и ваше право, что оно работает (данные выходят). Но его не выходить из программы, когда она завершена он просто зависает. – Lostsoul

+0

@Lostsoul: Я думаю, что это 'join()', который блокирует все. У меня нет этой проблемы на 'python-2.7' и' python-3.2', но у меня нет ' python-2.5', поэтому я не могу проверить его. Причина может заключаться в том, что [async results] (http://docs.python.org/py3k/library/multiprocessing.html#multiprocessing.pool.AsyncResult) являются недоступны или что-то еще, попробуйте добавить определенный возврат в 'new_awesome_function' и, возможно, проверите их каким-то образом, чтобы убедиться, что они' ready() 'или что-то в этом роде. –

+0

Хм, вы меня задумали .. Я не есть ли какие-либо результаты для отображения на самом деле, может это так? Я запускаю команду для обработки данных и загрузки их в базу данных. Я использую pyth на 2.6, но я могу попытаться обновиться и посмотреть, работает ли он. – Lostsoul

2

Multiprocessing не резьб.

Вы, вероятно, делать что-то Сорта, как этот

data = {} 

def new_awesome_function(a, b): 
    data[a] = b 

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

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

Самый простой способ заключается в использовании возвращаемых значений:

def new_awesome_function(a, b): 
    return a + b 

result = pool.apply_async(new_awesome_function, (1, 2)) 
# later... 
value = result.get() 

Смотрите документацию питона: http://docs.python.org/library/multiprocessing.html, для других методов, таких как Очереди, Трубы и менеджеров. То, что вы не можете сделать, это изменить состояние вашей программы и ожидать, что это сработает.

+0

Полезно знать, но я этого не делаю. У меня есть функция, которая полностью независима. Он принимает две переменные, и если переменные удовлетворяют определенным условиям, то они добавляются в базу данных. Единственное, что является внешним по отношению к функции, - это список, который я отправляю.Я мог бы усложнить его, на самом деле все, что мне нужно, - это способ отправки элементов списка (значение и счетчик, как в моем примере выше) функции, и эта функция выполняет свою работу при использовании моего процессора. – Lostsoul