Re: [PyQt] Are QThreads compatible with python's threading.RLock?
On Sat, Jul 26, 2008 at 3:48 AM, Phil Thompson wrote: > On Fri, 25 Jul 2008 17:41:22 -0400, Darren Dale wrote: >> I use a library that provides rudimentary thread safety of its objects > and >> file >> I/O using threading.RLock from the python standard library. Could anyone >> tell >> me if PyQt4's QThreads are compatible with these recursive locks? > > Other than the fact that they will both be implemented using the same OS > primitives, Python's and Qt's threading know nothing about each other. I had a reason to reeducate myself on this issue again today, since I write interfaces with PyQt4 but also rely upon third-party task managers and multiprocessing pools that are implemented with Python Threads and Locks. I believe the answer to my original question is: Yes, Python's Threads will respect PyQt4's locks (QMutex, QReadWriteLock) and PyQt4's QThread will respect Python's threading.RLock. Perhaps this conclusion is obvious to everyone but me. The script that convinced me is appended. It requires argparse (part of the stdlib in python-2.7), do "python test_locks.py -h" for help. Any of the following shows that one of the threads waits while the other holds the lock: python test_locks.py python test_locks.py -t python test_locks.py -l python test_locks.py -t -l Whereas, if locking is disabled entirely, threading execution is no longer synchronized (as expected): python test_locks.py -d I have tested with python-2.7 and PyQT4-4.8.3 linux and wuindows. I also tested (on linux) a modified version of the script to use a combination of Thread and QThread, which also works as one would hope. If there are additional considerations I have overlooked, I would be very interested to know. Darren --- import argparse import sys from threading import RLock, Thread import time from PyQt4.QtCore import QCoreApplication, QMutex, QThread, QReadWriteLock class DummyLock(object): def acquire(self): pass def release(self): pass def __enter__(self): return self def __exit__(self, *args): pass class QLock(QMutex): def acquire(self): self.lock() def release(self): self.unlock() def __enter__(self): self.acquire() return self def __exit__(self, *args): self.release() class MyQThread(QThread): def __init__(self, id, lock): QThread.__init__(self) self.id = id self.lock = lock def run(self): for i in range(5): with self.lock: for i in range(5): print self.id time.sleep(0.1) time.sleep(0.01) class MyThread(Thread): def __init__(self, id, lock): Thread.__init__(self) self.id = id self.lock = lock def run(self): for i in range(5): with self.lock: for i in range(5): print self.id time.sleep(0.1) time.sleep(0.01) parser = argparse.ArgumentParser( description='test combinations of threads and locks' ) parser.add_argument( '-t', '--thread', action='store_const', const=MyQThread, default=MyThread, help='use QThread instead of threading.Thread' ) parser.add_argument( '-l', '--lock', action='store_const', const=QLock, default=RLock, help='use QMutex instead of threading.RLock' ) parser.add_argument( '-d', '--disable-lock', action='store_true', dest='disable_lock', help="don't use a lock of any kind" ) args = parser.parse_args() if args.disable_lock: lock = DummyLock() else: lock = args.lock() thread1 = args.thread('Sid', lock) thread1.start() thread2 = args.thread('Nancy', lock) thread2.start() if args.thread is MyQThread: thread1.wait() thread2.wait() ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Are QThreads compatible with python's threading.RLock?
On Sun, 27 Jul 2008 08:55:02 -0400, Darren Dale <[EMAIL PROTECTED]> wrote: > On Saturday 26 July 2008 03:48:53 you wrote: >> On Fri, 25 Jul 2008 17:41:22 -0400, Darren Dale <[EMAIL PROTECTED]> > wrote: >> > I use a library that provides rudimentary thread safety of its objects >> >> and >> >> > file >> > I/O using threading.RLock from the python standard library. Could > anyone >> > tell >> > me if PyQt4's QThreads are compatible with these recursive locks? >> >> Other than the fact that they will both be implemented using the same OS >> primitives, Python's and Qt's threading know nothing about each other. > > Thanks Phil. The author of this other library I use added a mechanism to > accommodate alternative threading libraries: users can provide their own > lock > object, provided it is reentrant and respect python's context manager > protocol. So I think I can can do this: > > class MyRLock(QtCore.QMutex): > > def __init__(self): > super(MyRLock, self).__init__(QtCore.QMutex.Recursive) > > def __enter__(self): > return self.lock() > > def __exit__(self, type, value, traceback): > self.unlock() > > def acquire(self): > return self.lock() > > def release(self): > self.unlock() > > h5.config.RLock = MyRLock > > One last question, concerning context managers: I think the current PyQt4 > way > is: > > def foo(self): > with QMutexLocker(self.mutex): > [...] > > but if QMutex and friends had __enter__ and __exit__ methods, like > MyRLock, we > could do: > > def foo(self): > with self.mutex: > [...] > > Is there a reason (performance?) for using Qt's QMutexLocker to provide > the > context manager, rather than the QMutex itself? Probably just to keep the Python behaviour in line with the C++ behaviour. Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Are QThreads compatible with python's threading.RLock?
On Saturday 26 July 2008 03:48:53 you wrote: > On Fri, 25 Jul 2008 17:41:22 -0400, Darren Dale <[EMAIL PROTECTED]> wrote: > > I use a library that provides rudimentary thread safety of its objects > > and > > > file > > I/O using threading.RLock from the python standard library. Could anyone > > tell > > me if PyQt4's QThreads are compatible with these recursive locks? > > Other than the fact that they will both be implemented using the same OS > primitives, Python's and Qt's threading know nothing about each other. Thanks Phil. The author of this other library I use added a mechanism to accommodate alternative threading libraries: users can provide their own lock object, provided it is reentrant and respect python's context manager protocol. So I think I can can do this: class MyRLock(QtCore.QMutex): def __init__(self): super(MyRLock, self).__init__(QtCore.QMutex.Recursive) def __enter__(self): return self.lock() def __exit__(self, type, value, traceback): self.unlock() def acquire(self): return self.lock() def release(self): self.unlock() h5.config.RLock = MyRLock One last question, concerning context managers: I think the current PyQt4 way is: def foo(self): with QMutexLocker(self.mutex): [...] but if QMutex and friends had __enter__ and __exit__ methods, like MyRLock, we could do: def foo(self): with self.mutex: [...] Is there a reason (performance?) for using Qt's QMutexLocker to provide the context manager, rather than the QMutex itself? Thanks, Darren ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] Are QThreads compatible with python's threading.RLock?
On Fri, 25 Jul 2008 17:41:22 -0400, Darren Dale <[EMAIL PROTECTED]> wrote: > I use a library that provides rudimentary thread safety of its objects and > file > I/O using threading.RLock from the python standard library. Could anyone > tell > me if PyQt4's QThreads are compatible with these recursive locks? Other than the fact that they will both be implemented using the same OS primitives, Python's and Qt's threading know nothing about each other. Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
[PyQt] Are QThreads compatible with python's threading.RLock?
I use a library that provides rudimentary thread safety of its objects and file I/O using threading.RLock from the python standard library. Could anyone tell me if PyQt4's QThreads are compatible with these recursive locks? Thanks, Darren ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt