Многопроцессорный пул создает и уничтожает процессы на неопределенный срок - PullRequest
2 голосов
/ 18 февраля 2020

РЕДАКТИРОВАТЬ Этот короткий код ниже вызывает ту же проблему.

# top_level.py
import to_import

if __name__ == '__main__':
    # This does not work
    t = to_import.Test()
    from pprint import pprint
    pprint(t.test())
#to_import.py
import multiprocessing as mp


def test_func(a, b):
    return a * b


class Test:
    def __init__(self):
        self.pairs = list()
        for i in range(10):
            for j in range(10):
                self.pairs.append((i, j))

    def test(self):
        pairs = tuple(self.pairs)
        with mp.Pool() as pool:
            results = pool.starmap(test_func, pairs)
        return results


if __name__ == '__main__':
    # This works fine
    t = Test()
    from pprint import pprint
    pprint(t.test())

КОНЕЦ РЕДАКТИРОВАНИЯ

ДВОЙНОЕ РЕДАКТИРОВАНИЕ

Интересно, что этот код работает правильно при запуске из моей командной строки, в отличие от того, как я запускал его из Spyder ранее

EDIT END

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

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

# tin.py

from time import time
import multiprocessing as mp

def _points_from_face(points, grid_size):
    create 3d points within triangle on grid, uses other functions withinin this module

def _multiprocess_function(function, vals_gen, pool_size):
    with mp.Pool(processes=pool_size) as pool:
        results = pool.starmap(func=function,
                               iterable=vals_gen)
    return results

class Tin:
    def __init__(self, name, surface_dict):
        self.name = name
        self.points = surface_dict['Points']
        self.faces = dict(enumerate(surface_dict['Faces']))

    def generate_regular_grid(self, grid_size,
                              multiprocess=False,
                              pool_size=(mp.cpu_count()//2)):
        return_grid = dict()
        if pool_size < 1:
            multiprocess = False
        if multiprocess:
            faces_tuple = tuple(self.faces.values())
            vals_tuple = tuple((tuple(self.points[pid] for pid in face), grid_size)
                               for face in faces_tuple)
            results = _multiprocess_function(_points_from_face,
                                             vals_tuple,
                                             pool_size)
            for result in results:
                return_grid.update(result)
        else:
            for face in self.faces.values():
                points = tuple(self.points[pid] for pid in face)
                return_grid.update(_points_from_face(points, grid_size))
        return return_grid

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

Но когда я импортирую tin.py в другой скрипт и пытаюсь использовать многопроцессорность, программа застревает, создавая и убивая процессы снова и снова, ничего не возвращая.

например,

# landxml.py

from time import time
from tin import Tin

def parse_landxml(xml_path: str, print_times=False) -> Tin:
    read xml file and return Tin contained within

if __name__ == '__main__':
    st = time()
    surface = parse_landxml('some_tin.xml',
                             print_times=True)
    grid = surface.generate_regular_grid(grid_size=2,
                                         print_times=True,
                                         multiprocess=True)

Нужно ли мне держите все в одном длинном скрипте или есть способ, которым я все еще могу использовать многопроцессорную обработку внутри импортированного скрипта.

Кроме того, land xml .py будет импортирован в сам другой файл, это может вызвать то же самое проблема снова?

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