【发布时间】:2013-02-06 23:07:06
【问题描述】:
标准 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() 的两个进程是否会发生冲突?例如:
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() 的每个分支中添加了一个打印语句, 并且似乎每个进程都会重新计算缓存中的所有 fib 值。 也许缓存不是共享的,毕竟?如果不共享,我会伤人 如果有一种流程安全的方式来共享它(以节省更多的计算)。
【问题讨论】:
标签: python-2.7 multiprocessing decorator memoization