Как правильно высвободить ресурсы из инициализатора многопроцессорного пула? - PullRequest
1 голос
/ 03 апреля 2019

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

Я могу инициализировать эти ресурсы, используя initializer из multiprocessing.Pool. Однако нет функции shutdown для правильного освобождения ресурсов.

Снятие примера с https://stackoverflow.com/a/28508998:

socket = None
def init(address, port):
    global socket
    socket = magic(address, port)

def job(data):
    global socket
    assert socket is not None
    return send(socket, data)

pool = multithreading.Pool(N, init, [address, port])
pool.map(job, ['foo', 'bar', 'baz'])

В этом примере, как я могу убедиться, что сокет закрыт правильно? Или, в более общем смысле, выполнить закрывающий код для каждого работника?

Этот ответ https://stackoverflow.com/a/13136120/2375130 предлагает следующий обходной путь (адаптированный для этого примера):

import time

def destroy(x):
    global socket
    socket.close()
    time.sleep(1) # to ensure that this worker does not run on two elements from range
    return None

pool.map_async(g, range(N), 1)

Это похоже на взлом. Есть ли лучший вариант, который не предполагает повторной реализации пула сам?

...