Reputation: 612
I'm developing a large optimzation tool using Qt. For a better CPU usage I use QThreads. Then I move worker objects (derived from QObject, containing non QObject data members) into the threads. Everything looks fine, builds fine and runs smoothly on Linux using GCC and Qt 4.8
However using MinGw using Qt 5.5 under Windows, the calculation took much longer. It seems like the threads are blocking somewhere in the calculation and are serialized. I displayed some debug messages to ensure that the threads are working correctly. It seems like there is a bottelneck that exists on Windows but not under Linux. I don't think that the Qt Version makes a difference, I'd rather think the problem is caused by MinGw. The OS are Windows 7 and Debian. I use the compiled MinGw binaries of Qt5.
Is there any further configuration for MinGw's Qt build necessary? Or is there a problem using non QObject members, when moving worker objects into threads? Could this be a problem with the different thread types, QThread uses internally? Thank you in advance :-)
EDIT:
The starting ob the threads looks like this.
for (int i = 0; i < this->numberOfCores; i++)
{
QThread *thread = new QThread(this);
thread->setObjectName("Thread " + QString::number(i));
Calculator *calculator = new Calculator(/* Skip parameters */);
calculator->moveToThread(thread);
connect(calculator, SIGNAL(debugInfo(DebugData)), this, SIGNAL(debugInfo(DebugData)));
connect(this, SIGNAL(startCalculator()),
calculator, SLOT(startCalculation()));
connect(calculator, SIGNAL(solutionFound(Solution*)),
this, SLOT(addSolution(Solution*)));
connect(calculator, SIGNAL(calculationFinished()), this, SLOT(calculatorFinished()));
thread->start(QThread::HighestPriority);
I used this approach multiple times and it always worked.
The Calculator then just calculates the solution. Each calclator has its own data und there cannot be a race condition. They all work on completly different data.
Upvotes: 0
Views: 344
Reputation: 98505
On each signal emission, the high priority threads will be synchronizing with the lower priority thread that receives the cross-thread slot calls. That's probably the source of platform differences: different kernels address temporary priority boosts differently, and on top of that on Linux the event loops are from glib, on Windows they are not. They will behave differently when it comes to synchronization across threads of differing priorities. If the receiving thread spends a lot of time in the event loop actively dispatching events, it can wreak havoc on high priority threads.
Perhaps counter-intuitively, the solution might be as simple as not making the computation threads high priority.
Anyway, your users will hate you for depriving them of interactive performance for some calculations that should be running in the background. The computation threads will preempt default priority GUI threads, the system will feel very sluggish to an interactive user, and that applies to your own UI too! The calculation threads should be of a lower priority instead. This of course assumes that the computations aren't used to drive interaction (e.g. physics engine in a game); if they do, and you think the application deserves it, you must raise the priority of the entire process.
Upvotes: 1
Reputation: 21
How do you start the thread?
#include <QObject>
#include <QThread>
class _Object : public QObject
{
Q_OBJECT
public:
explicit _Object(QObject *parent = 0);
void _setup(QThread &th);
public slots:
void do_stuff_you_want();
};
and the _Object.cpp
:
#include "_object.h"
_Object::_Object(QObject *parent) :
QObject(parent)
{
}
void _Object::_setup(QThread &thread)
{
connect(&thread,SIGNAL(started()),this,SLOT(do_stuff_you_want()));
}
void _Object::do_stuff_you_want(){......}
In main.cpp
:
#include <all_u_need>
#include <QThread>
#include "_object.h"
int main(.. .. ..)
{
...
QThread thread_obj_runns_in;
_Object object_to_run;
object_to_run._setup();
object_to_run.moveToThread(&thread_obj_runns_in);
thread_obj_runns_in.start();
...
return app.exec();
}
I had got a lot of problems in using run()
and QThread subclasses.
As I started to use it like this, I never got thread problems anymore.
What I want to say is : create a QObject and move it to a thread and don't subclass QThread.
I hope I could help you.
Upvotes: 0