Предположим, что вы используете объект multiprocessing.Pool
, и вы используете параметр initializer
конструктора для передачи функции инициализации, которая затем создает ресурс в глобальном пространстве имен. Предположим, что у ресурса есть менеджер контекста. Как бы вы справлялись с жизненным циклом ресурса, управляемого контекстом, при условии, что ему нужно прожить жизнь в процессе, но правильно ли очиститься в конце?
До сих пор у меня есть что-то вроде этого:
resource_cm = None
resource = None
def _worker_init(args):
global resource
resource_cm = open_resource(args)
resource = resource_cm.__enter__()
С этого момента процессы пула могут использовать ресурс. Все идет нормально. Но обработка очистки немного сложнее, так как класс multiprocessing.Pool
не предоставляет аргумент destructor
или deinitializer
.
Одна из моих идей - использовать модуль atexit
и зарегистрировать очистку в инициализаторе. Что-то вроде этого:
def _worker_init(args):
global resource
resource_cm = open_resource(args)
resource = resource_cm.__enter__()
def _clean_up():
resource_cm.__exit__()
import atexit
atexit.register(_clean_up)
Это хороший подход? Есть ли более простой способ сделать это?
EDIT: atexit
, похоже, не работает. По крайней мере, не так, как я использую его выше, поэтому прямо сейчас у меня все еще нет решения этой проблемы.