[PyQt] Multithreading, signals, reference counting and crash

Ilya Volkov nxsofsys at gmail.com
Thu Feb 11 13:14:35 GMT 2016


Hi all,

We have some problems with sending python objects between threads by
signals with Qt.QueuedConnection type. If python object was sent from one
thread to another by signal, its reference counter does not increment, and
object can be destroyed in first thread before slot in second thread will
be called which leads to a crash.

I made example which illustrates this situation (also available on github:
https://gist.github.com/nxsofsys/d80487e7605eb7061d88 ):

from PyQt5.QtCore import QObject, QThread, pyqtSignal
from PyQt5.QtCore import qDebug, QCoreApplication, Qt
import time
import sys

class SomeThread(QObject):

    signal = pyqtSignal(QObject)

    def __init__(self):
        QObject.__init__(self)
        self.thread = QThread()
        self.wait = self.thread.wait
        #
        # self.signal.connect(self.signalHandler, type =
Qt.QueuedConnection)
        self.moveToThread(self.thread)
        self.signal.connect(self.signalHandler, type = Qt.QueuedConnection)
        self.thread.started.connect(self.run)
        self.thread.start()

    def signalHandler(self, obj):
        qDebug("signalHandler obj ref counts: " + str(sys.getrefcount(obj)))

    def run(self):
        qDebug("Thread sleeps for 1 sec")
        time.sleep(1)
        qDebug("Process events now")
        QCoreApplication.processEvents()
        self.thread.exit()

app = QCoreApplication([])
th = SomeThread()

# obj = QObject()
def someFunc():
    obj = QObject()
    qDebug("obj ref counts before emit: " + str(sys.getrefcount(obj)))
    th.signal.emit(obj)
    qDebug("obj ref counts after emit: " + str(sys.getrefcount(obj)))

someFunc()
qDebug("Process main events")
QCoreApplication.processEvents()
qDebug("Process main events done")
th.thread.wait()

I think in this case signal emit should increment reference counter for a
python object preventing it from destruction. Just comment "obj = QObject"
in someFunc and uncomment  "# obj = QObject()" before function definition,
and script runs without crash.

Thanks,
-- 
Ilya Volkov
nxsofsys at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20160211/c06449a8/attachment.html>


More information about the PyQt mailing list