Python缓存/记忆和线程锁定

时间:2014-01-16 08:16:40

标签: python multithreading caching

当被问到我的应用程序应该打开一个.csv文件时,从它做一个字典。我还需要缓存该数据并从缓存中返回它的“年轻”。与装饰者做到了这一点:

def memorize(key, period):
    """
    Memorizing decorator. Returning cached data
    if its validity period is not expired
    """
    def _decoration_wrapper(func):
        def _caching_wrapper(*args, **kwargs):
            cache_key = key
            now = time.time()

            if _timestamps.get(cache_key, now) > now:
                return _cache[cache_key]

            ret = func(*args, **kwargs)
            _cache[cache_key] = ret
            _timestamps[cache_key] = now + period
            return ret
        return _caching_wrapper
    return _decoration_wrapper

工作正常但我需要使其线程安全。我更喜欢用Lock类来做。所以我可以肯定,在一个period中只有一个线程,一次将执行包装函数。

所以我现在想要怎么做。
如何进行测试的信息将非常感激 非常感谢。

1 个答案:

答案 0 :(得分:0)

我会这样做:

import threading

#1
lock = threading.Lock() # use this line if theadsafety for _cache is important

def memorize(key, period):
    """
    Memorizing decorator. Returning cached data
    if its validity period is not expired
    """
    #2
    lock = threading.Lock() # use this line if theadsafety for a key is important
    def _decoration_wrapper(func):
        #3
        lock = threading.Lock() # use this line if theadsafety for  the function is important
        def _caching_wrapper(*args, **kwargs):
            cache_key = key
            now = time.time()

            if _timestamps.get(cache_key, now) > now:
                return _cache[cache_key]
            with lock:
                if _timestamps.get(cache_key, now) > now:
                    return _cache[cache_key]
                ret = func(*args, **kwargs)
                _cache[cache_key] = ret
                _timestamps[cache_key] = now + period
                return ret
        return _caching_wrapper
    return _decoration_wrapper

#

  1. 你有一个共享的资源,缓存。锁定这个可能是有用的。它只是一个字典,然后GlobalInterpreterLock会为你做这个。
  2. 锁定钥匙。如果两个函数具有相同的装饰器,则它们不会并行执行。
  3. 锁定功能。这意味着函数将在其他线程中等待其他线程的其他调用完成,然后再次查找缓存。
  4. 你如何测试?首先编写测试,然后输入更多的锁和超时,以确保两个函数不会同时执行。 我没有一般指南,但这些测试真的很难看。