Как правильно запоминать при использовании ProcessPoolExecutor?

Я подозреваю, что что-то вроде:

@memoize
def foo():
    return something_expensive

def main():
    with ProcessPoolExecutor(10) as pool:
        futures = {pool.submit(foo, arg): arg for arg in args}
        for future in concurrent.futures.as_completed(futures):
            arg = futures[future]
            try:
                result = future.result()
            except Exception as e:
                sys.stderr.write("Failed to run foo() on {}\nGot {}\n".format(arg, e))
            else:
                print(result)

Не будет работать (при условии, что @memoize является типичным кешем на основе dict) из-за того, что я использую многопроцессорный пул, а процессы не имеют большого общего доступа. По крайней мере, это не работает.

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


person GL2014    schedule 23.07.2019    source источник
comment
ты что-нибудь искал? есть много вопросов по совместному использованию состояния с использованием multiprocessing, или вы пробовали какой-либо из подходов упоминается в документах?   -  person juanpa.arrivillaga    schedule 23.07.2019
comment
Поскольку запоминание требует сохранения аргументов и результатов более ранних вызовов — как бы оно ни было реализовано — очень маловероятно, что оно сработает, когда запомненная функция используется более чем в одном процессе, поскольку у одного из них есть собственное отдельное пространство памяти. Это принесет пользу нескольким вызовам внутри каждого процесса, хотя общее преимущество, вероятно, будет уменьшено. Тем не менее, ваша идея травления звучит так, как будто ее стоит использовать, IMO, поскольку консервированные данные могут использоваться более чем одним процессом, если каждый из них загружает их.   -  person martineau    schedule 23.07.2019


Ответы (1)


Вы можете использовать Manager.dict из многопроцессорной обработки, которая использует Manager для проксирования между процессами и сохранения в общем dict, который можно мариновать. Я решил использовать многопоточность, потому что это приложение, связанное с вводом-выводом, и пространство общей памяти потока означает, что мне не нужны все эти вещи менеджера, я могу просто использовать dict.

person GL2014    schedule 18.08.2019