Многопроцессорная обработка Python не может использовать функции из другого модуля

#python #multiprocessing #python-multiprocessing #multiprocessing-manager

Вопрос:

Обновление: он работает после обновления моего Spyder до 5.0.5. Спасибо всем!

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

Моя идея состоит в том, чтобы разделить задачу на 5 процессов и сохранить ее result . Однако при запуске кода он вернул пустой список.

Но, если я удалю result = add_one(result) randomize_data функцию, код будет работать идеально. Таким образом, ошибка должна быть вызвана использованием функций из других модулей ( Testing.test ) внутри многопроцессорной обработки.

Вот add_one функция из Testing.test :

 def add_one(x):
    return x 1
 

Как я могу использовать функции из других модулей внутри процесса? Спасибо.

 import multiprocessing
import numpy as np
import pandas as pd

def randomize_data(mean, cov, n_init, proc_num, return_dict):
    result = pd.DataFrame()
    for _ in range(n_init):
        temp = np.random.multivariate_normal(mean, cov)
        result = result.append(pd.Series(temp), ignore_index=True)
    
    result = add_one(result)
    return_dict[proc_num] = result

if __name__ == "__main__":

    from Testing.test import add_one

    mean = np.arange(0, 1, 0.1)
    cov = np.identity(len(mean))
    
    manager = multiprocessing.Manager()
    return_dict = manager.dict()
    jobs = []
    
    for i in range(5):
        p = multiprocessing.Process(target=randomize_data, args=(mean, cov, 2000, i, return_dict, ))
        jobs.append(p)
        p.start()
    
    for proc in jobs:
        proc.join()
    
    result = return_dict.values()
 

Ответ №1:

Проблема здесь довольно очевидна: вы импортировали add_one в локальной области, а не в глобальной. Из-за этого ссылка на эту функцию существует только внутри вашего main-if. Переместите этот оператор импорта в другие, в верхнюю часть вашего файла, и ваш код должен работать.

 import multiprocessing
import numpy as np
import pandas as pd
from Testing.test import add_one
 

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

1. Хм, теперь на компиляцию уходит целая вечность. Мой spyder не закончил компиляцию программы с тех пор, как вы ответили. Есть ли здесь проблема с версией? Я использую Python 3.7.6

2. Ну, в настоящее время это, похоже, вообще не имеет смысла. Версия Python не должна иметь отношения к этому. Какой-нибудь бесконечный цикл где-нибудь в вашем коде?

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

4. Попробуйте другую среду разработки, возможно, это проблема со Spyder. Но для меня код с моим встроенным ответом также работает и завершается.

5.Нет, ваше объяснение неверно. После того, как оператор from Testing.test import add_one будет выполнен в исходном коде операции, он add_one должен стать доступным для randomize_data вызова. Если вы распечатаете dir(sys.modules['__main__']) , вы увидите и randomize_data то, и add_one другое .