2014-09-16 2 views
3

LRU 캐시를 구현하는 C 확장자가 https://github.com/pbrady/fastcache입니다. 필자는 최근에 캐싱을 상당히 많이 사용하는 애플리케이션 (SymPy)에서 타임 아웃 신호가 손실되고 애플리케이션이 계속 실행되는 것으로 나타났습니다. 이는 순수한 Python LRU 캐시 (예 : functools.lru_cache)가 아닌 C 확장자를 사용하는 경우에만 발생합니다 https://github.com/pbrady/fastcache/issues/26.PyErr_CheckSignals가 신호를받지 않음

나는 PyErr_CheckSignals()에 대한 호출로 루틴을 소홀히 했으므로 신호가 자주 손실되지는 않지만 여전히 발생합니다. 호출하는 동안 캐시는 PyObject_Hash, PyDict_Get/Set/DelItem 및 PyObject_Call (miss의 경우)을 호출합니다.

여기 SymPy 코드의 관련 단편은 (제한 시간은 정수)입니다 :

def _timeout(self, function, timeout): 
    def callback(x, y): 
     signal.alarm(0) 
     raise Skipped("Timeout") 
    signal.signal(signal.SIGALRM, callback) 
    signal.alarm(timeout) # Set an alarm with a given timeout 
    function() 
    signal.alarm(0) # Disable the alarm enter code here 

은 뭔가 신호를 덮어 쓸 수 있는가? 그렇다면이 문제를 어떻게 해결할 수 있습니까?

답변

0

실제로 여기에 진짜 수수께끼가 없지만 조금 까다 롭습니다.

PyErr_CheckSignals()에 대한 호출 외에도, PyObject_Hash, PyDict_Get/Set/DelItem에 대한 호출을 통해 제어가 전달 될 때마다 신호가 인터프리터에 의해 포착 될 수 있습니다. 이러한 함수 중 하나에서 인터프리터에 의해 신호가 잡히면 콜백 함수로 인해 예외가 트리거됩니다 (처리 된 이후에는 신호가 사라집니다). 그러나, 내 모든 함수의 반환 값을 확인하지 못했습니다 (즉, 내 인수가 해시 가능이므로 PyDict_SetItem의 반환 값을 확인하지 못했습니다.) 따라서 예외가 무시되고 프로그램에서 신호가있는 것처럼 계속 실행됩니다 일어나지 않았다.

Ondrej 감사합니다.