Неожиданное поведение глобальной переменной при использовании с многопроцессорным модулем - PullRequest
0 голосов
/ 05 мая 2019

Я переписывал свое приложение.Хотя я хотел использовать глобальную переменную для передачи некоторой информации в функцию.Я заметил, что значение глобальной переменной не изменилось после ее изменения.Кроме того, я заметил, что поведение отличается в зависимости от синтаксиса «pool.map_async».Ниже приведен код, который воспроизводит эту ошибку.

Первый пример: когда у задания нет параметров, но я передаю "job ()" в "= func", например, "func = job ()" (передача только «задания» выглядит так, как будто процесс не выполняется)

from multiprocessing import Pool

x = None

def job():
    print(x,"Inside Job")

def main():
    global x
    x = 10
    pool = Pool(1)
    li = [0]
    pool.map_async(iterable=li,func=job())
    pool.close()
    pool.join()
    print("End of main")

if __name__ == "__main__":
    print(x,"Before")
    main()
    print(x,"After")

Вывод на консоль

None Before
10 Inside Job
End of main
10 After

Вывод, как и ожидалось, значение x внутризадание правильное.

Теперь, если позволить функции заданию принять любой аргумент, как показано ниже

from multiprocessing import Pool

x = None

def job(z):
    print(z)
    print(x,"Inside Job")

def main():
    global x
    x = 10
    pool = Pool(1)
    li = [0]
    pool.map_async(iterable=li,func=job)
    pool.close()
    pool.join()
    print("End of main")

if __name__ == "__main__":
    print(x,"Before")
    main()
    print(x,"After")

Вывод на консоль

None Before
0
None Inside Job
End of main
10 After

Вывод показываетчто изменение значения x не было замечено.

Может кто-нибудь объяснить, почему использование «global» не работает, когда функция «job» принимает аргумент?

Я на Python 3.7.0

1 Ответ

1 голос
/ 05 мая 2019

Ваш первый пример - Just Wrong.Функция job должна принимать аргумент.

Здесь в этом примере все движется на юг:

    pool.map_async(iterable=li, func=job())

Вы хотели:

    pool.map_async(iterable=li, func=job)

.

Возвращаемое значение из вашей функции - None, поэтому вы синхронно выполняете job() в контексте main, а затем передаете полученный None в map_async.Оператор global в main повлиял на поиск x.

Второй пример выглядит намного лучше.Он правильно отображает 0.

Вместо того, чтобы пытаться сохранить значения с помощью global, вы были бы счастливее, если бы вы хранили такие значения в объекте и передавали объект в job в качестве аргумента.Например:

class Point:

    def __init__(self, x, y):
        self.x = x
        self.y = y

points = [Point(3, 4), Point(5, 6)]
pool.map_async(iterable=points, func=job)

Многопроцессорная документация указывает на map () docs.Вместе с тем, что может быть предоставлена ​​только одна итерация, их рекомендации сводятся к следующему:

функция должна принимать [один] аргумент

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