I followed this tutorial for QThreads
:
http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
The only problem I am having is killing the QThread
. I have a flag in the process()
loop of the worker object that I push into my QThread
instance that is called m_ShouldSendFrames
. If that flag is flipped to false, then my processing loop breaks and the worker object emits the finished()
signal.
The problem I have is that I cannot seem to get my worker object in the QThread
to receive my stopSendingFrames()
signal from the main thread. I connect that ( and the connection returns 'true' ) like this:
connect(this, SIGNAL(stopSendingFrames()), m_UdpWorkerBlended, SLOT(stopFrames()),Qt::QueuedConnection); // Stop broadcasting
In my killUdpThread
function, I'd like to emit the stopSendingFrames()
signal and have the m_UdpWorker
object get it. But it never does! The only way I can get that flag to change is to do this in the killUdpThread
:
m_UdpWorkerBlended->stopFrames();
That however, is unsafe and randomly crashed because it is not called from the QThread
that the worker is running in.
I've also tried the invokeMethod
way - but it never fires the slot either:
QMetaObject::invokeMethod(m_UdpWorkerBlended,"stopFrames",Qt::QueuedConnection);
Can someone please help me understand why I cannot call invokeMethod
or use signals to fire my slot running in the worker object in the QThread
but I can call it ( unsafely ) directly? Thanks!
Start thread function:
int UdpThreadController::startUdpThread(int frameType, int port, QString ip) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Starting Thread! Frame type is: " << frameType;
#endif
// Check for type of frame to emit
if ( frameType == 0 ) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Frames are vl";
#endif
// Delete any existing threads / workers
killUdpThread(0);
// New objects
m_UdpThreadBlended = new QThread();
m_UdpWorkerBlended = new UdpWorker();
// Assign Port and IP and Frame Type
m_UdpWorkerBlended->m_ShouldSendFrames = true;
m_UdpWorkerBlended->m_Port = port;
m_UdpWorkerBlended->m_AddressToUse = ip;
m_UdpWorkerBlended->m_FrameType = frameType;
// Push into thread
m_UdpWorkerBlended->moveToThread(m_UdpThreadBlended);
// Connect signals
connect(this, SIGNAL(stopSendingFrames()), m_UdpWorkerBlended, SLOT(stopFrames()),Qt::QueuedConnection); // Stop broadcasting
connect(m_UdpThreadBlended, SIGNAL(started()), m_UdpWorkerBlended, SLOT(process()));
connect(m_UdpWorkerBlended, SIGNAL(finished()), m_UdpThreadBlended, SLOT(quit()));
connect(m_UdpWorkerBlended, SIGNAL(finished()), m_UdpWorkerBlended, SLOT(deleteLater()));
connect(m_UdpThreadBlended, SIGNAL(finished()), m_UdpThreadBlended, SLOT(deleteLater()));
m_UdpThreadBlended->start();
// All done
return 0;
Kill thread function:
int UdpThreadController::killUdpThread(int frameType) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Killing Thread! Frame type is: " << frameType;
#endif
// Check for type of frame to emit
if ( frameType == 0 ) {
// Delete any existing threads / workers
if ( m_UdpWorkerBlended ) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Emit signal to kill thread...";
#endif
// Stop broadcasting
m_UdpWorkerBlended->stopFrames();
}
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Success ending UDP...";
#endif
// All done
return 0;
}
Thanks for the input. I solved it by having a singleton that has a flag that the processing loop in my worker object in the QThread reads each loop iteration. It is protected by a QReadWrite lock.
int UdpThreadController::killUdpThread(int frameType) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Killing Thread! Frame type is: " << frameType;
#endif
// Check for type of frame to emit
if ( frameType == 0 ) {
// Delete any existing threads / workers
if ( m_UdpWorkerBlended ) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Setting flag to kill thread...";
#endif
// Stop broadcasting
m_Lock.lockForWrite();
m_ShouldSendFramesBlended = false;
m_Lock.unlock();
}
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Success ending Blended UDP...";
#endif
// All done
return 0;
bool UdpThreadController::shouldContinueSendingFrames(int frameType) {
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Checking if we should continue processing: " << frameType;
#endif
// Check for type of frame to emit
if ( frameType == 0 ) {
m_Lock.lockForRead();
#if SINGLETON_CAMERA_UDP_DEBUG
qDebug() << "Should continue Blended: " << m_ShouldSendFramesBlended;
#endif
bool shouldBroadcast = m_ShouldSendFramesBlended;
m_Lock.unlock();
// All done
return shouldBroadcast;
}