gpt4 book ai didi

python - 一个线程安全的 memoize 装饰器

转载 作者:太空宇宙 更新时间:2023-11-03 11:33:06 25 4
gpt4 key购买 nike

我正在尝试制作一个适用于多线程的 memoize 装饰器。

我明白了,我需要使用缓存作为线程之间的共享对象,并获取/锁定共享对象。我当然要启动线程:

for i in range(5):
thread = threading.Thread(target=self.worker, args=(self.call_queue,))
thread.daemon = True
thread.start()

worker 在哪里:

def worker(self, call):
func, args, kwargs = call.get()
self.returns.put(func(*args, **kwargs))
call.task_done()

当然,当我同时向多个线程发送一个装饰有备忘录函数(如 this )的函数时,问题就开始了。

如何将备忘录的缓存实现为线程间的共享对象?

最佳答案

最直接的方法是对整个缓存使用一个锁,并要求对缓存的任何写入都首先获取锁。

在您发布的示例代码中,在第 31 行,您将获取锁并检查结果是否仍然缺失,在这种情况下,您将继续计算并缓存结果。像这样:

lock = threading.Lock()
...
except KeyError:
with lock:
if key in self.cache:
v = self.cache[key]
else:
v = self.cache[key] = f(*args,**kwargs),time.time()

您发布的示例在字典中为每个函数存储一个缓存,因此您还需要为每个函数存储一个锁。

但是,如果您在高度争议的环境中使用此代码,它的效率可能会低得令人无法接受,因为线程必须相互等待,即使它们计算的不是同一件事。您可以通过在缓存中为每个键存储一个锁来改进这一点。不过,您还需要全局锁定对锁存储的访问,否则在创建每键锁时会出现竞争条件。

关于python - 一个线程安全的 memoize 装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13079842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com