2014-05-08 168 views
0

工作通讯我跟着这个教程QThreadshttp://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/与QThread的不与信号/插槽

我遇到的唯一问题是杀QThread。我在工作对象的process()循环中插入一个标志,我将其插入我的QThread实例中,该实例被称为m_ShouldSendFrames。如果该标志被翻转为假,那么我的处理循环就会中断并且工作对象将发出信号finished()

我的问题是,我似乎无法让QThread中的我的工作对象从主线程接收我的stopSendingFrames()信号。我是连接(以及连接返回“真”)是这样的:

connect(this, SIGNAL(stopSendingFrames()), m_UdpWorkerBlended, SLOT(stopFrames()),Qt::QueuedConnection); // Stop broadcasting 

在我killUdpThread功能,我想发出stopSendingFrames()信号,并有m_UdpWorker对象得到它。但它从来没有!我可以得到的标志改变的唯一方法是做到这一点的killUdpThread

m_UdpWorkerBlended->stopFrames(); 

也不过是不安全的,并随机崩溃,因为它不是从工人正在运行QThread称为

我也尝试了invokeMethod方式 - 但它永远不会触发插槽之一:

QMetaObject::invokeMethod(m_UdpWorkerBlended,"stopFrames",Qt::QueuedConnection); 

是否有人可以帮助我了解为什么我不能叫invokeMethod或使用信号来触发我的插槽在W运行orker对象在QThread但我可以直接调用它(不安全)?谢谢!

启动线程函数:

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; 

杀死线程功能:

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; 

    } 
+0

你可以分享你发出'stopSendingFrames'信号的代码吗? – deGoot

+0

嗨,所以在列表末尾的killUdpThread函数中,我试图发出信号stopSendingFrames来代替m_UdpWorkerBlended-> stopFrames()。我用这个替换列表中的行:“emit stopSendingFrames()”。工人对象从来没有得到信号。 – PhilBot

+0

当您尝试发信号时,工作线程是否“忙”?一旦线程空闲,信号只能被传递。另外,你有没有考虑过使用''代替线程?我觉得它更方便。 – deGoot

回答

0

感谢您的输入。我通过一个拥有一个标志的单例解决了这个问题,在QThread中我的工作对象中的处理循环读取每个循环迭代。它受QReadWrite锁保护。

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; 

    }