標準の memoize デコレータのキャッシュはプロセスセーフですか?
たとえば、次のデコレータを定義するとします。
import functools
def memoize(func):
cache = {}
@functools.wraps(func)
def memoized(*args):
result = None
if args in cache:
result = cache[args]
else:
result = func(*args)
cache[args] = result
return result
return memoized
そして、再帰関数の計算を高速化するためにそれを使用しようとしているとします。
@memoize
def fib(n):
result = 1
if n > 1:
result = fib(n-1) + fib(n-2)
return result
ここで、fib() を計算する 2 つのプロセスが衝突する可能性があるのだろうか? 例えば:
if __name__ == "__main__":
from multiprocessing import Process
p1 = Process(target=fib, args=(19,))
p2 = Process(target=fib, args=(23,))
p1.start()
p2.start()
p1.join()
p2.join()
私の最初の考えは、キャッシュは fib のコンテキストで保存されるため、プロセス間で共有され、競合状態につながる可能性があるということでした。しかし、起こりうる最悪の事態は、たとえば、 fib(17) が計算されていないと両方が考え、両方が先に進んで並行して計算し、同じ結果を次々に保存することだと思います-理想的ではありませんが、恐ろしいことではないと思います。しかし、プロセスセーフな方法でそれを行う方法があるかどうかはまだ疑問です.
編集: memoized() の各ブランチに print ステートメントを追加しました。各プロセスがキャッシュ内のすべての fib 値を再計算するようです。結局、キャッシュが共有されていないのではないでしょうか? 共有されていない場合は、それを共有するためのプロセスセーフな方法があるかどうかを気にします(さらに計算を節約するため)。