[PyQt] Freezes and crashes with signal autoconnection

Phil Thompson phil at riverbankcomputing.com
Tue Oct 20 17:37:42 BST 2009


On Fri, 16 Oct 2009 13:41:44 -0700 (PDT), Christian Roche
<christian.roche.fr at gmail.com> wrote:
> Hi again!
> 
> 
> Phil Thompson-5 wrote:
>> 
>> If you have a list of the QThread instances you can scan the list when
>> finished() is received to see which one it is. There is an obvious race
>> condition with that approach.
>> 
> 
> I don't know if this race condition is obvious but I'm personally unable
to
> identify it. Could you please kindly elaborate a bit for a
multi-threading
> newbie ? :-)

If two threads finish at the same time you may not be able to identify
which is which.

> Phil Thompson-5 wrote:
>> 
>> You could define a method in your QThread sub-class that finished() is
>> connect to. That method just emits another signal but with the QThread
>> instance as an argument.
>> 
> 
> I also have a hard time understanding this one. How could finished()
> connect
> to a method in the originating thread, which by definition is supposed
not
> to exist anymore since it has emitted this very signal? Or is the
semantics
> for this signal more complex?

I think you are confusing the QThread and the thread itself. The former
will still exist when the latter has finished.

> By the way, I applied the first approach you suggested, i.e., I use
> Qt.BlockingQueuedConnection when passing arguments in signals from
threads
> to main, and I now have a slot that collects finished() signals, browse
the
> list of threads and deletes those that it finds effectively finished. The
> behavior is definitely better on Linux, although not perfect, however on
> Windows I still get lots of crashes with no error messages at all.
> Sometimes, but not always, the application spurts some weird error
messages
> in the middle of the run, not right before the crash, like 
> 
> 
>> NotImplementedError: QAbstractListModel.rowCount() is abstract and must
>> be
>> overridden
>> 
> although this method is overriden of course, and works most of the time;
or
> (the application is using shelve):
> 
> 
>> Traceback (most recent call last):
>>   File "E:\Python\gallery\gallery\gallery.py", line 107, in data
>>     return QVariant(self.getLink(index).getPixmap())
>>   File "E:\Python\gallery\gallery\threads.py", line 76, in getPixmap
>>     filepath = imageCache.getImageFile(self)
>>   File "E:\Python\gallery\gallery\threads.py", line 148, in getImageFile
>>     if self.cache.has_key(url):
>>   File "E:\Programs\Python\lib\shelve.py", line 107, in has_key
>>     return key in self.dict
>>   File "E:\Programs\Python\lib\_abcoll.py", line 329, in __contains__
>>     self[key]
>>   File "E:\Programs\Python\lib\bsddb\__init__.py", line 266, in
>> __getitem__
>>     self._checkOpen()
>> AttributeError: 'str' object has no attribute '_checkOpen'
>> 
> or simply (this one arrives right before the crash):
> 
> 
>> NotImplementedError
>> 
> 
> It all seems to be related to the ImageLink instances emitting a signal
> towards a QAbstractListModel layoutChanged signal once download is
> complete.
> I have no problem when I remove this signal (except of course that the
> display does not refresh >-() However this all happens in the main thread
> as
> far as I can tell. I'm going to try and extract a use case for that one
but
> I'm afraid it won't be easy. In the meantime if you could point me to a
> possible likely cause I'd be very grateful!

I can't remember if you are using snapshots or not, but there are some
issues fixed related to looking up Python reimplementations of virtual
methods.

Phil


More information about the PyQt mailing list