ThreadPool не освобождает память? - PullRequest
0 голосов
/ 02 февраля 2019

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

import numpy as np
from multiprocessing.pool import ThreadPool

def worker(x):
    # Bloat the memory footprint of this function
    a = x ** x
    b = a + x
    c = x / b
    return hash(c.tobytes())   

tasks = (np.random.rand(1000, 1000) for _ in range(500))

with ThreadPool(4) as pool:
    for result in pool.imap(worker, tasks):
        assert result is not None

При запуске этого фрагмента можно легко наблюдать огромный скачок в объеме памяти, используемой Python.Однако я ожидал, что это будет иметь почти такое же поведение, как

for task in tasks:
    assert worker(task) is not None

, чья стоимость памяти незначительна.

Как мне изменить фрагмент, чтобы применить функцию worker ккаждый массив, используя ThreadPool?

1 Ответ

0 голосов
/ 02 февраля 2019

Оказывается, объяснение довольно простое.Модификация примера для создания случайного массива только внутри рабочего решит проблему:

def worker(x):
    x = x()
    # Bloat the memory footprint of this function
    a = x ** x
    b = a + x
    c = x / b
    return hash(c.tobytes())

tasks = (lambda: np.random.rand(1000, 1000) for _ in range(500))

Кажется, что ThreadPools.imap внутренне превратит генератор tasks в список или что-то подобное.Это, конечно, потребовало бы одновременного хранения всех 500 случайных массивов в памяти.

...