0

Я пытаюсь обновить общую переменную (массив numpy в пространстве имен) при использовании модуля многопроцессорности. Однако переменная не обновляется, и я не понимаю, почему.Совместная переменная многопроцессорности не обновляется

Вот пример кода для иллюстрации этого:

from multiprocessing import Process, Manager 
import numpy as np 

chunk_size = 15 
arr_length = 1000 
jobs = [] 
namespace = Manager().Namespace() 
namespace.arr = np.zeros(arr_length) 
nb_chunk = arr_length/chunk_size + 1 


def foo(i, ns): 
    from_idx = chunk_size*i 
    to_idx = min(arr_length, chunk_size*(i+1)) 
    ns.arr[from_idx:to_idx] = np.random.randint(0, 100, to_idx-from_idx) 

for i in np.arange(nb_chunk): 
    p = Process(target=foo, args=(i, namespace)) 
    p.start() 
    jobs.append(p) 
for i in np.arange(nb_chunk): 
    jobs[i].join() 

print namespace.arr[:10] 

ответ

0

Вопрос заключается в том, что Manager().Namespace() объект не замечает что вы меняете что-либо с помощью ns.arr[from_idx:to_idx] = ... (поскольку вы работаете над внутренней структурой данных) и, таким образом, не распространяются на другие процессы.

This answer объясняет очень хорошее, что здесь происходит.

Чтобы это исправить, создайте список как Manager().List() и передать этот список процессов, так что ns[from_idx:to_idx] = ... распознается как изменение и распространяется на процессы:

from multiprocessing import Process, Manager 
import numpy as np 

chunk_size = 15 
arr_length = 1000 
jobs = [] 
arr = Manager().list([0] * arr_length) 

nb_chunk = arr_length/chunk_size + 1 


def foo(i, ns): 
    from_idx = chunk_size*i 
    to_idx = min(arr_length, chunk_size*(i+1)) 
    ns[from_idx:to_idx] = np.random.randint(0, 100, to_idx-from_idx) 

for i in np.arange(nb_chunk): 
    p = Process(target=foo, args=(i, arr)) 
    p.start() 
    jobs.append(p) 
for i in np.arange(nb_chunk): 
    jobs[i].join() 

print arr[:10] 
1

Вы не можете разделить встроенные объекты, такие как list, dict между процессами в Python. Для обмена данными между процессом, Python's multiprocessing обеспечивают структуру двух данных:

Также читайте: Exchanging objects between processes

+0

нормально, но как я мог бы принять преимущество в том, что в каждом процессе я не имею доступа к одному и тому же пространству памяти массива? – GuillaumeA

+0

Как и в вашем текущем коде, передавая их как аргумент функции ('foo()' в вашем случае). Вы можете ссылаться на [Выполнение нескольких асинхронных функций и получение возвращаемого значения каждой функции] (http://stackoverflow.com/questions/40536287/running-multiple-asynchronous-function-and-get-the-returned-value-of- каждый-functi), вопрос, который я задавал в прошлом. Он имеет ответ с использованием 'Queue' –