[PyKDE] Re: Threading problem with PyQt4 and Macosx

Phil Thompson phil at riverbankcomputing.co.uk
Sat Feb 24 11:12:35 GMT 2007


On Saturday 24 February 2007 12:42 am, Matt Newell wrote:
> On Friday 23 February 2007 14:34, Matt Newell wrote:
> > On Friday 23 February 2007 12:52, Matt Newell wrote:
> > > On Friday 23 February 2007 12:38, Michael Guntsche wrote:
> > > > On Feb 23, 2007, at 20:43, Matt Newell wrote:
> > >
> > > ...
> > >
> > > > Hello Matt,
> > > >
> > > > Can you try and change the connect to a QueuedConnection? It looks
> > > > like it is using a "DirectConnection" now.
> > > > I was sure I tried that before, but back then I was using events and
> > > > not signals.
> > >
> > > It's already (correctly) using a queued connection to send the signal.
> > > I've already tracked it down further and eliminated one of the deadlock
> > > code paths by putting a /ReleaseGIL/ annotation on QLabel::setText.
> > > There is another deadlock though happening in the connect call which
> > > i'm tracking down now.
> > >
> > > > I tried it on my computer, but although the "connect" returns True I
> > > > do not get the emitted signal in my main thread.
> > > > I do not understand why.
> > >
> > > Hmm, i'm not sure why that would happen.
> >
> > So here's the deal.  In order to avoid deadlocks we must avoid running
> > any Qt code that will require a lock while the GIL is locked.  This is
> > because we can't avoid the opposite, which is acquiring the GIL while Qt
> > is holding a lock( For example Qt holds a lock while copying signal data
> > for queued connections, and we have to run python code for that. )  To
> > avoid a deadlock we must avoid one or the other.
> >
> > This means that any Qt calls that do a connect, or create/destroy any
> > qobjects must first release the GIL.  There may be other code paths in Qt
> > that require the same care.
> >
> > Try testing with this patch, it eliminates all deadlocks for me.
>
> I still get deadlocks when destroying the threads unless I add /ReleaseGIL/
> to the QThread dtor.
>
> I think that right now there are many potential deadlocks in PyQt.  All
> QObject and derived classes need their ctors and dtors marked /ReleaseGIL/.
> All connect/disconnect functions, any functions that indirectly delete or
> create qobjects, etc.  Essentially the entire api needs to be reviewed.

There are a number of strategies for dealing with this...

1. Manual inspection of the Qt source code and applying /ReleaseGIL/ where 
needed.

2. Automatically release the GIL whenever any Qt call is made. This was how 
SIP v3 worked (because it supported earlier versions of Python that didn't 
support PEP 311) and is still available in SIP v4 using the undocumented -g 
flag.

3. Automatically release the GIL whenever any Qt call is made from a QObject 
derived class. The assumption is that this will cover the vast majority of 
cases. Any other cases would have to be identified through bug reports.

1. is out of the question - unless somebody can recommend a good C++ source 
code analyzer.

I tend towards 3.

Comments?

Phil




More information about the PyQt mailing list