Solved How do I suspend a Qt Thread
-
Hi, I have a thread say B. I want to stop this thread B from another thread say A. I tried the following ways. But the thread B keeps running. The program control doesnt come out of the ThreadB event loop. Is there a way to suspend a thread safely and immediately?
Here is my example code:
File: main.cppthreadA->Start(); threadB->Start();
threadA: event loop: in fileA.cpp
void threadA::run() { while(!m_quit) { if (threadB->isRunning()) { threadB->quit(); threadB->wait(); } }
I also tried it this way to stop the thread B.
void threadA::run() { while(!m_quit) { if (threadB->isRunning()) { threadB->wait(); threadB->quit(); } }
Here is the thread B event loop in fileB.cpp
void threadB::run() { while(!m_quit) { //check if USB device is connected //Do XYZ } }
-
use worker class for the threads and send a signal from worker A to worker B to stop thread B
https://wiki.qt.io/QThreads_general_usage -
@Subbu The default implementation of
QThread::run
callsexec()
that starts and runs an event loop. That loop can be stopped by callingquit()
. You have overriddenrun
and there's no Qt event loop running in it, soquit()
does nothing. You have your own loop and stop condition using a member variable, so you need to use that i.e.void threadA::run() { while(!m_quit) { if (threadB->isRunning()) { threadB->m_quit = true; //or using a setter method if you have one } } }
Is there a way to suspend a thread safely and immediately
Immediately - no. Threads run independently, possibly on different cores or CPUs. ASAP is the closest thing you can get, but not immediately as in the next CPU instruction.
Safely - yes, but it takes a bit of effort. Your code is not safe. If thread B is stopped and destroyed just after you callif (threadB->isRunning())
but beforethreadB->quit();
then your code will crash from calling a method on destroyed object. You need proper synchronization - make sure that both thread objects are alive when they call methods on each other. -
@Subbu
Everything that @Chris-Kawa said.If you are in charge of the code/behaviour of thread B, see void QThread::requestInterruption() and bool QThread::isInterruptionRequested() const for one way of A stopping B. But this may not be your case.
-
Thanks Fellas for the quick response. You have given me many solutions.