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;

    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top