我有以下代码:
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 的全部意义。这与 Python 垃圾收集有关吗?如果是这样,那一定意味着 QMutexLocker 在 Python 中根本不可用?
最佳答案
您没有正确使用 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 会做它应该做的事情,只要作用域结束就会解锁。但是在 Python 中,正如您所发现的,不应依赖垃圾收集器来进行解锁。通过 with
语句的上下文管理器非常适合这种情况。您可以通过此类的 C++ 示例显示它只是在函数顶部创建的方式来判断。而 python 版本同时具有 __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
关于python - PyQt:QMutexLocker 未在异常时释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11261663/