python - PyQt:QMutexLocker 未在异常时释放

标签 python pyqt

我有以下代码:

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/

相关文章:

python - GUI 在循环时变得无响应

python - 延迟加载子项 Qtreeview

python - `not` 运算符与 python 列表的奇怪行为

python - 创建 .exe 文件后没有这样的文件或目录 - Python

python - PDF 输出不适用于 Pyqt5 和 Python 3.5

python - 如何将 QScintilla 语法突出显示应用于 PyQt4 中的 QTextEdit?

python - reshape 图像的 4D numpy 数组正在改变图像数字

python - json.dumps 对我不起作用

python - 像 ls 这样的输出列表

Python 命名空间 : How to make unique objects accessible in other modules?