Изменение «глобального» массива с помощью процессов пула

#python

#python

Вопрос:

Сначала приношу извинения за небольшой дамп кода, который последует, но я провел вечер, делая свои первые шаги в многопроцессорном модуле; с моими предыдущими знаниями, полученными из OpenMPI fortran. У меня возникли проблемы с приведенным ниже кодом в том смысле, что, хотя все потоки появляются, запускаются и т.д. И имеют доступ ко всем правильным значениям (как глобальным, так и локальным), изменения, каждое из которых воздействует на массив numpy points, не сохраняются. Я пробовал как устанавливать массив как «глобальный», так и выделять его в отдельный класс для доступа к нему, оба безрезультатно. Я предполагаю, что мне не хватает некоторого фундаментального понимания.

Важные части:

 points = np.ones( N )

def explore(pos,rad):
    #find range of points for comparison
    low = []
    high = []
    for dim in pos:
        low.append( int( floor( (dim - rad - 0.5*radius) / radius ) ) )
        high.append( int( ceil( (dim   rad   0.5*radius) / radius ) ) )

    #check for overlap
    for x in xrange(low[0],high[0] 1):
        for y in xrange(low[1],high[1] 1):
            for z in xrange(low[2],high[2] 1):
                if points[x%N[0],y%N[1],z%N[2]]:
                    point = (x*radius,y*radius,z*radius)
                    distance = (point[0]-pos[0])**2   (point[1]-pos[1])**2   (point[2]-pos[2])**2 
                    if distance <= (rad (0.5*radius))**2:
                        points[x%N[0],y%N[1],z%N[2]] = 0
    return

pool = Pool()
for i in xrange( atoms ):
    pos = ...
    rad = ...
    pool.apply_async(explore,(pos,rad,))
pool.close()
pool.join()  
  

Комментарии:

1. Для любого, кого интересует, как обойти это ограничение, я обнаружил, что решением было изменить переменные массива в функции обратного вызова; предварительно сохранив все точки, которые передают условие в explore, к этому через список. К сожалению, я не могу сказать вам, почему это так, но, тем не менее, это исправление. Всего наилучшего, Али

Ответ №1:

Если вы используете multiprocessing.pool , то вы создаете здесь не потоки, а полноценные процессы. В документе говорится:

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

РЕДАКТИРОВАТЬ: Альтернативно, есть недокументированный multiprocessing.pool.ThreadPool , с тем же API, что и multiprocessing.pool . Но да, это недокументировано, что означает, что оно может сломаться / исчезнуть и т.д.

Комментарии:

1. Да, вам нужно было бы использовать общие объекты в общей памяти, чтобы заставить что-то работать таким образом. docs.python.org/library /…