[Solved] Best way to handle GUI thread in multi-threaded application?
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:
QThread *bthr = new QThread();
B *bObj = new B();
connect(bthr, SIGNAL(started()), bObj, SLOT(calc()));
QTimer::singleShot(1000, NULL, NULL);
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!
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.
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.
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?
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.