2012-06-29 3 views
4

에 해제되지 나는 다음과 같은 코드가 있습니다 예외가 잠금 나던 던져 삭제 될 것으로 보인다 경우PyQt는 : QMutexLocker 예외

def query(self,query): 
    lock = QMutexLocker(self.mutex) 
    reply = self.conn.query(query) 
    if (re.search("error", reply) != None): 
    raise GeneralError("Query error") 

    #more code... 
    return reply 

지금, 뮤텍스가 해제되지 않습니다 원인입니다. 나는 도처에 "del lock"을 할 수는 있지만 qmutexlocker의 모든 부분을 제거합니다. 이것은 파이썬 가비지 콜렉션과 관련이 있습니까? 그렇다면 QMutexLocker는 Python에서 전혀 사용할 수 없다는 것을 의미합니까? 당신이 예외를 발생 이전에 출시 된 뮤텍스를 원하는 경우

답변

1

, 다음을 해제 :

def query(self, query): 
    lock = QMutexLocker(self.mutex) 
    reply = self.conn.query(query) 
    if re.search("error", reply): 
     lock.unlock() 
     raise GeneralError("Query error") 

당신이 lock 그것이 바로 출시 될 것으로 범위를 벗어나면, 당신은 너무 많은 기대를 희망하는 경우 통역사의 잠금 장치를 해제해야하는시기와 이유를 정확히 알고 있으므로 수행하십시오.

일반적으로 파이썬 또는 다른 곳에서는 가능한 가장 작은 가능한 동작에 뮤텍스를 바인딩해야합니다. 나는 쿼리가 실제로 무엇을 하든지간에 보호가 필요하며 여전히 self.conn.query을 호출 한 후에 쿼리가 필요하다는 것을 알고 있다고 가정합니다.

코멘트에 대한 응답으로 추가 :

하는 공정 점이다

내가 미스 않았다 "QMutexLocker을 의미합니다 전혀 사용할 수 없습니다." 난 당신이 가능성 주장한다 PySide.QtCore.QMutexLocker 언급하는 가정 : 이제

을의 PySide.QtCore.QMutexLocker 객체가 소멸 될 때 뮤텍스는 항상 잠금이 해제됩니다 (때 기능을 반환하는 사물함은 자동 변수이기 때문이다).

파이썬에서 변수 저장 클래스 auto이 없기 때문에 가능성이 희박합니다. 나는 이것이 더 많은 조사를 통해 "C++ 라이브러리를 포장하고 범위 지정 의미 작업을한다고 가정하자"라고 생각합니다. 이 추측이 맞다면 확실한 잠금 해제를 보장하기 위해 with statement을 유용하게 사용할 수 있습니다.

+0

고맙습니다 I 파이썬이 GC로 작성된 것처럼이 방법이 두렵다.그러나 내가 말했듯이 이것은 QMutexLocker의 전체 아이디어가 무의미합니다. 잠금 해제에 대해 걱정할 필요가 없기 때문입니다. 또한 그것은 예외를 던지지 않는 Im 때 작동하는 것, 다소 이상합니다. 잠금 장치가 삭제 된 시점을 알지 못하는 것과 같은 문제가 있습니까? – Rolle

+0

나는이 대답이 약간 일반적이고 정확한 정보를 둘러싼다고 생각하고, 단지 가정을한다. 제대로 사용될 때 QMutexLocker를 사용할 수 있다는 데는 의문의 여지가 없습니다. 하지만 잠금을 최소화하기 위해 중요한 코드 섹션을 잠그는 것에 대해서는 완전히 동의합니다. – jdi

+0

동의, 그냥 추측했다, 그래서 나는 당신의 대답을 upvoted. – msw

7

QMutexLocker를 올바르게 사용하고 있지 않습니다. 컨텍스트 관리자처럼 사용하십시오 :

from PyQt4.QtCore import QMutex, QMutexLocker 

def bad_lock(aLock): 
    locker = QMutexLocker(aLock) 
    print "Locked" 
    raise RuntimeError("Test exception") 

    return "Should not get here" 

def good_lock(aLock): 
    with QMutexLocker(aLock): 
     print "Locked" 
     raise RuntimeError("Test exception") 

    return "Should not get here" 

lock = QMutex() 

bad_lock(lock) 
print lock.tryLock() 
# False 

lock.unlock() 

good_lock(lock) 
print lock.tryLock() 
# True 

테스트에서는 첫 번째 예에서 잠금 잠금이 여전히 잠겨 있음을 확인했습니다. 두 번째 경우 예외가 발생하면 컨텍스트 관리자는 함수를 종료하기 전에 잠금을 해제합니다.

C++에서 사용되는 경우 QMutexLocker는 범위가 끝날 때마다 잠금 해제되는 것으로 가정합니다. 그러나 파이썬에서 발견 한 것처럼 가비지 수집기가 잠금 해제를 수행해서는 안됩니다. 컨텍스트 관리자를 통해 with 성명이 완벽합니다. 이 클래스의 C++ 예제가 단순히 함수의 맨 위에 만들어지는 것을 보여주는 방식으로 알 수 있습니다. 반면 파이썬 버전은 __enter____exit__ 메소드를 모두 가지고 있습니다.

마지막으로는 with 상황은이 같은 것을 할 수 있도록, 잠금이 자리에있을 필요가의 양을 제한하는 잠금에서 중요한 코드 블록을 포장 할 수 있습니다 :

def good_lock(aLock): 

    # do a bunch of stuff here 
    ... 

    # critical section 
    with QMutexLocker(aLock): 
     # do critical stuff here 
     ... 

    # do other stuff here 
    ... 

    return True 
+0

니스는 Py : – Rolle

+0

의 성명서와 같은 위대한 일이라는 것을 결코 알지 못했습니다 @Rolle : 여기에있는 다른 답변만큼 좋지 않은 것 같습니다. ;-) 그 사람은 QMutexLocker가 신뢰할 수 없다고 말했습니다. – jdi