Неожиданное поведение при использовании Multiprocessing.Pool внутри цикла for - PullRequest
0 голосов
/ 20 марта 2019

Вот мой код:

import multiprocessing as mp
import numpy as np

def foo(p):
    global i
    return p*i

global lower, upper
lower = 1
upper = 4

for i in range(lower, upper):
    if __name__ == '__main__':
        dataset = np.linspace(1, 100, 100)
        agents = mp.cpu_count() - 1
        chunksize = 5
        pool = mp.Pool(processes=agents)
        result = pool.map(foo, dataset, chunksize)
        print result
        print i
        pool.close()
        pool.join()

Консоль распечатывает массив [3, 6, 9, ..., 300] три раза с целыми числами 1,2,3 между каждым массивомраспечатывать.Так что я правильно перебираю нижний и верхний (не включительно), но я ожидал, что сначала он распечатает массив [1, 2, 3, ..., 100], а затем [2, 4, 6, ...,200] и, наконец, [3, 6, 9, ..., 300].Я не понимаю, почему он только передает окончательное значение i в foo и затем отображает это трижды.

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Сделайте меня локальным, и использование functools.partial может решить вашу проблему:

import multiprocessing as mp
import numpy as np
import functools

def foo(p,i):
    return p*i

global lower, upper
lower = 1
upper = 4

for i in range(lower, upper):
    if __name__ == '__main__':
        dataset = np.linspace(1, 100, 100)
        agents = mp.cpu_count() - 1
        chunksize = 5
        pool = mp.Pool(processes=agents)
        foo2 = functools.partial(foo, i)
        result = pool.map(foo2, dataset, chunksize)
        print(result)
        print(i)
        pool.close()
        pool.join()
1 голос
/ 20 марта 2019

Когда вы запускаете новый процесс, это то, что он видит:

import multiprocessing as mp
import numpy as np

def foo(p):
    global i
    return p*i

global lower, upper
lower = 1
upper = 4

for i in range(lower, upper):
    if __name__ == '__main__':
        # This part is not run, as
        # in a different process,
        # __name__ is set to '__mp_main__'
# i is now `upper - 1`, call `foo(p)` with the provided `p`

И после выполнения этого приказывают запустить foo (Он должен запустить весь сценарий снова, чтобы выяснить,что такое foo, просто из-за того, как работает травление)

Итак, после этого i будет upper - 1 и всегда будет возвращать p * 3.

Вы хотите сделать i параметром, заданным для foo, или каким-либо конкретным мультипроцессорным объектом совместного использования памяти, как описано ниже здесь

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