Почему mulitprocessing.Pool запускается, но никогда не завершается? - PullRequest
1 голос
/ 07 мая 2020

Я пытаюсь использовать mulitprocessing.Pool, чтобы ускорить выполнение функции в диапазоне входных данных. Кажется, что процессы были вызваны, поскольку мой диспетчер задач указывает на существенное увеличение загрузки моего процессора, но задача никогда не завершается. Никаких исключений не возникает, во время выполнения или иным образом.

from multiprocessing import Pool

def f(x):
    print(x)
    return x**2

class Klass:
    def __init__(self):
        pass

    def foo(self):
        X = list(range(1, 1000))
        with Pool(15) as p:
            result = p.map(f, X)

if __name__ == "__main__":
    obj = Klass()
    obj.foo()
    print("All Done!")

Интересно, что, несмотря на рост загрузки ЦП, print(x) никогда ничего не выводит на консоль.

Я переместил функцию f вне класса, как было предложено здесь , но безрезультатно. Я попытался добавить p.close() и p.join(), но безуспешно. Использование других методов класса Pool, таких как imap, приводит к ошибкам TypeError: can't pickle _thread.lock objects и, похоже, делает шаг в сторону от примера использования во введении Python Документация по многопроцессорной обработке .

В добавление к путанице, если я попытаюсь запустить приведенный выше код достаточное количество раз (убивая зависшее ядро ​​после каждой попытки), код начнет стабильно работать, как ожидалось. Обычно требуется около двадцати попыток, прежде чем это «щелкнет» на месте. Перезапуск моей IDE возвращает теперь работающий код обратно в прежнее неисправное состояние. Для справки, я использую дистрибутив Anaconda Python (Python 3.7) со Spyder IDE на Windows 10. У моего процессора 16 ядер, поэтому Pool(15) не вызывает больше процессов, чем у меня есть CPU. ядра. Однако выполнение кода в другой среде IDE, такой как Jupyter Lab, дает такие же неверные результаты.

Другие предположили , что это может быть недостаток самого Spyder, но предложение использовать mulitprocessing.Pool вместо mulitprocessing.Process тоже не работает.

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Может быть связано с this from python do c:

Примечание. Функциональность этого пакета требует, чтобы модуль main был импортируемым детьми. Это описано в Руководстве по программированию, однако стоит указать здесь. Это означает, что некоторые примеры, такие как примеры multiprocessing.pool.Pool, не будут работать в интерактивном интерпретаторе.

, а затем этот комментарий к их примеру:

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

ОБНОВЛЕНИЕ: найденная информация здесь похоже, подтверждает, что использование пула из интерактивного интерпретатора будет иметь переменный успех. Это руководство также распространяется ...

... руководство [состоит] в том, чтобы всегда использовать функции / классы, определения которых можно импортировать.

Это решение, описанное в общих чертах здесь и который работает у меня (каждый раз) с использованием вашего кода.

1 голос
/ 07 мая 2020

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

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