2012-10-26 3 views
4

여러 스레드에서 작동하는 메모 데코레이터를 만들려고합니다.스레드 세이프 메모 데코레이터

스레드간에 공유 객체로 캐시를 사용해야하고 공유 객체를 획득/잠금해야한다는 것을 이해했습니다. 근로자가

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

이다 : 나는 물론 스레드를 실행하고있어 나는 메모 기능과 장식 기능을 보내고있을 때

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

문제는 물론, 시작을 (this을 같은) 같은 시간에 많은 스레드에.

어떻게 메모 캐시를 스레드간에 공유 객체로 구현할 수 있습니까?

답변

2

가장 간단한 방법은 전체 캐시에 단일 잠금을 사용하고 캐시에 대한 모든 쓰기가 먼저 잠금을 가져와야한다는 것입니다.

게시 한 예제 코드에서 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() 

당신은뿐만 아니라 기능별 잠금을 저장해야 할 것 있도록, 사전에 저장을 기능에 따라 캐시를 게시 한 예.

매우 논쟁의 여지가있는 환경에서이 코드를 사용하는 경우 스레드가 동일한 것을 계산하지 않아도 서로 기다려야하기 때문에 아마도 비효율적 일 것입니다. 캐시에 키당 잠금을 저장하여이를 향상시킬 수 있습니다. 하지만 잠금 저장소에 대한 액세스를 전역 적으로 잠글 필요가 있습니다. 그렇지 않으면 키 별 잠금을 만드는 경쟁 조건이 있습니다.

관련 문제