I have the following code:
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
Now, if the exception is thrown lock doesnt seem to be deleted, cause the mutex is not released. I can ofcourse do "del lock" everywhere, but that takes away the whole point of qmutexlocker. Does this have to do with Python garbage-collection? If so, that must mean QMutexLocker is not usable at all in Python?
You aren't using the QMutexLocker properly. Use it like a context manager:
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
In the test, you see in the first example, the lock returns still locked. In the second, when the exception is raised, the context manager releases the lock before leaving the function.
When used in C++, I am sure the QMutexLocker does what it is supposed to, unlocking whenever the scope ends. But in Python, as you have discovered, the garbage collector should not be relied upon to do the unlocking. Context managers via the with
statement are perfect for this. You can tell by the way the C++ examples of this class show it simply being created at the top of the function. Whereas the python version has both an __enter__
and __exit__
method.
Lastly, the with
context lets you wrap the critical code blocks in a lock to limit the amount of the the lock needs to be in place, so you can do something like this:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With