Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent PyQt objects from garbage collecting from different thread?

I am using Qt 4.7 and PyQt 4.7 to build a multi-threaded GUI program. I've been carefully managing PyQt objects so that they stay in one UI thread to avoid synchronization issues and there is no problem in general.

But sometimes, at the moment the python garbage collector is activated from other thread, the destructor of Qt object is called right there and the following assertion fails from inside Qt.

I can define QT_NO_DEBUG even for the debug version and it should be fine because objects being collected hardly cause a synchronization problem. But still, I don't think that's a good idea to turn off other debug messages. How do I prevent this from happening?

#if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
{
    QThread *currentThread = QThread::currentThread();
    QThread *thr = receiver->thread();
    Q_ASSERT_X(currentThread == thr || !thr,
               "QCoreApplication::sendEvent",
               QString::fromLatin1("Cannot send events to objects owned by a different thread. "
                                   "Current thread %1. Receiver '%2' (of type '%3') was created in thread %4")
               .arg(QString::number((quintptr) currentThread, 16))
               .arg(receiver->objectName())
               .arg(QLatin1String(receiver->metaObject()->className()))
               .arg(QString::number((quintptr) thr, 16))
               .toLocal8Bit().data());
    Q_UNUSED(currentThread);
    Q_UNUSED(thr);
}
#elif defined(Q_OS_SYMBIAN) && defined (QT_NO_DEBUG) 
like image 871
Kyung-Kook Park Avatar asked Oct 20 '10 06:10

Kyung-Kook Park


People also ask

Is Java garbage collection multithreaded?

Java's garbage collector is very robust in terms of circular referencing, I don't see why It won't work with multiple threads running at the same time. So it is safe for you to assume that you don't need to write a special program for garbage collection, because java will do it for you very effectively.

How can we prevent garbage collection in Java?

The best way to stop Java garbage collection from happening is to use the experimental Epsilon GC, no-op garbage collector from JDK 11. Learn how and when to use it. You can't force garbage collection in Java.

Does Python do automatic garbage collection?

Python has an automated garbage collection. It has an algorithm to deallocate objects which are no longer needed. Python has two ways to delete the unused objects from the memory.

How often does Python garbage collector run?

Any time a reference count drops to zero, the object is immediately removed. 295 * deallocated immediately at that time. A full collection is triggered when the number of new objects is greater than 25% of the number of existing objects.


1 Answers

This problem popped up on the PyQt mailing list in the thread

"subtle bug in PyQt in combination with Python garbage collector"
http://www.riverbankcomputing.com/pipermail/pyqt/2011-August/030376.html

Kovid Goyal proposed a workaround in
http://www.riverbankcomputing.com/pipermail/pyqt/2011-August/030378.html

where he wrote:

As a workaround in my projects, I disable the automatic garbage collector and run garbage collection manually in the GUI thread via QTimer.

He posted a code example there.

like image 53
Adrian Buehlmann Avatar answered Sep 22 '22 17:09

Adrian Buehlmann