[Solved] Best way to handle GUI thread in multi-threaded application?
-
Hi,
I have classes A, B & C.
In a function in class A, I am creating object of B in a different thread. In the B object I am creating as many objects of C as no of cores. So the actual number crunching is happening in class C for say 4 threads. The thread of object of B is waiting for all these threads to finish after which it will finish itself & there will only be the GUI thread in A object. Now when the number crunching is happening the GUI is freezing & shows "[Not Responding]" in title bar. I don't want the GUI to be active (i.e. allow button clicking, etc) but atleast it should not freeze & show "Not Responding". With this background let me explain in code:A::func1()
{
//...some stuff
QThread *bthr = new QThread();
B *bObj = new B();
connect(bthr, SIGNAL(started()), bObj, SLOT(calc()));
bObj->moveToThread(bthr);
bthr->start();
while(!bthr->isFinished())
{
qApp->processEvents();
QTimer::singleShot(1000, NULL, NULL);
//QThread::currentThread()->wait(1000);
}
bthr->wait();
disconnect(bthr, SIGNAL(started()), s, SLOT(calc()));
//... some more stuff
}Please overlook syntax errors.
In the calc() SLOT of class B, I am creating 4 objects of class C & moving them to different threads for number crunching.
So to avoid the GUI freezing I used the above code, which perfectly does what is needed.
But the CPU performance which was previously 100% has dropped to 90%.
Now if I comment the QTimer & instead use the QThread::wait(), then also I am getting what is required.
But it is again affecting performance + throwing qWarning() "thread tried to wait on itself"So my question is what is the best way to handle a GUI thread to avoid freezing but not affect performance.
Sorry about the long post!
Thanks :) -
I think Qt Slots are not thread safe , while signals are thread safe. So keep some locking mechanism to improve GUI performance. GUI it self runs in main thread.
-
Hi,
Why not just have a slot connected to bthr's finished slot ?
You disable/lock/etc... your application GUI in func1() and enable/release/etc... in your "threadFinished" slot. Thus no need for that loop + the wait.
-
Hi SGaist,
Thank You for your reply.
In my code:bthr->wait(); disconnect(bthr, SIGNAL), s, SLOT)); //… some more stuff
As you can see I am performing some operations after the wait() gets over.
What you are saying is I think, bthr->start(); should be the last line in A::func1(); correct?If yes then how would I be able to resume from the point where bthr->wait() is called?
I will have to move all this code into the new SLOT right?
But this would be a bad coding technique...right?Sorry for asking so many questions.
Can you please tell me how you leave the GUI thread in your multi-threaded applications?
Thanks again. -
It all depends on what your thread does and what your cleanup code does.
Calling wait will suspend the calling thread, so if it's the GUI thread, it'll freeze it.