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
テストでは、最初の例で、ロックがロックされたままになっていることがわかります。2番目の例では、例外が発生すると、コンテキストマネージャーは関数を終了する前にロックを解放します。
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