Я использую многопроцессорный пул для распараллеливания некоторых дорогих вычислений. Допустим, некоторые из этих вычислений основаны на внешних данных, таких как файлы на жестком диске, сетевые подключения или подпроцессы, на которых выполняются сценарии на других языках программирования.
Я могу инициализировать эти ресурсы, используя 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)
Это похоже на взлом. Есть ли лучший вариант, который не предполагает повторной реализации пула сам?