multiprocessing.Pool, кажется, работает в Windows, но не в Ubuntu? - PullRequest
4 голосов
/ 02 августа 2011

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

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

Краткое описание моей проблемы: при использовании multiprocessing.Pool в Python я не всегда могу получить количество рабочих, которых я запрашиваю. Когда это происходит, программа просто останавливается.

Я целый день работал над решением, а потом я подумал о комментарии Ноа по моему предыдущему вопросу. Он сказал, что он работает на его машине, поэтому я передал код своему коллеге, который работает на машине Windows с 64-битным дистрибутивом Python 2.7.1 Enthoughts. У меня то же самое с большой разницей, что мой работает на Ubuntu. Я также упоминаю, что у нас обоих есть Wingware Python IDE, но я сомневаюсь, что это имеет какое-то значение?

Есть две проблемы с моим кодом, которые не возникают, когда мой коллега запускает код на своем компьютере.

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

  2. Когда я могу получить четырех рабочих, которых я запрашиваю (что происходит примерно 1 из 5 или около того), полученные цифры (простые случайные числа) Точно одинаковы для всех четырех изображений. Это не относится к моему коллеге.

Что-то очень подозрительно, и я очень благодарен за любую помощь, которую вы, ребята, можете предложить.

код:

import multiprocessing as mp
import scipy as sp
import scipy.stats as spstat
import pylab

def testfunc(x0, N):
    print 'working with x0 = %s' % x0
    x = [x0]
    for i in xrange(1,N):
        x.append(spstat.norm.rvs(size = 1)) # stupid appending to make it slower
        if i % 10000 == 0:
            print 'x0 = %s, i = %s' % (x0, i)
    return sp.array(x)

def testfuncParallel(fargs):
    return testfunc(*fargs)


# Define Number of tasks.
nTasks = 4
N = 100000

if __name__ == '__main__':

    """
    Try number 1. Using multiprocessing.Pool together with Pool.map_async
    """
    pool = mp.Pool(processes = nTasks) # I have 12 threads (six cores) available so I am suprised that it does not get access to nTasks = 4 amount of workers

    # Define tasks:
    tasks = [(x, n) for x, n in enumerate(nTasks*[N])] # nTasks different tasks

    # Compute parallel: async - asynchronically, i.e. not necessary in order.
    result = pool.map_async(testfuncParallel, tasks)

    pool.close() # These are needed if map_async is used
    pool.join()

    # Get results:
    sim = sp.zeros((N, nTasks)) 

    for nn, res in enumerate(result.get()):    
        sim[:, nn] = res

    pylab.figure()
    for i in xrange(nTasks):
        pylab.subplot(nTasks,1, i + 1)
        pylab.plot(sim[:, i])

    pylab.show()

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

С уважением, Matias

Ответы [ 2 ]

4 голосов
/ 02 августа 2011

У меня нет решения для вашей первой проблемы.Фактически, я могу запускать ваш код многократно на моем 64-битном Ubuntu-боксе с Enthought's Python 2.7.1 [EPD 7.0-2 (64-битный)]. edit : Оказывается, проблема связана с вашей IDE (Wingware).Очевидный обходной путь - запуск сценария вне среды IDE.

Что касается второго вопроса, то происходит то, что в Unix каждый рабочий процесс наследует одно и то же состояние генератора случайных чисел от родительского процесса.Вот почему они генерируют идентичные псевдослучайные последовательности.Все, что вам нужно сделать, чтобы это исправить, это позвонить по номеру scipy.random.seed вверху testfunc:

def testfunc(x0, N):
    sp.random.seed()
    print 'working with x0 = %s' % x0
    ...
1 голос
/ 02 августа 2011

Обновление: Оказывается, это не имеет ничего общего с matplotlib или бэкэндами, а скорее с ошибкой, связанной с многопроцессорностью в целом.Мы исправили это для версии Wing 4.0.4+.Обходной путь - не устанавливать точки останова в коде, выполняемом в подпроцессах.

Похоже, поддержка Wing IDE matplotlib для бэкэнда Tkinter плохо взаимодействует с многопроцессорной обработкой.Когда я пытаюсь этот пример, он падает в коде TCL / Tk.Я подозреваю, что человек, работающий в Windows, использовал другой бэкэнд matplotlib.

Отключение "поддержки цикла событий matplotlib" в свойствах проекта на вкладке "Расширения", кажется, обходит его.

Илидобавление следующего, по-моему, исправляет эту проблему, когда включена «поддержка цикла событий matplotlib».

import matplotlib matplotlib.use ('WXAgg')

Это будет работать только при наличиибэкэнд WXAgg.Другие бэкэнды, поддерживаемые Wing IDE (таким образом, что графики остаются интерактивными, даже если процесс отладки приостановлен), это GTKAgg и Qt4Agg, но я еще не пробовал.

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

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