title: QThread terminate and affinity
body: <p>This example is for testing QThread. The main objective is to be able to run one time consuming blocking method in a dedicated thread and
  being able to terminate and restart the thread at any point. The blocking method is a 3rd party lib which is outside our control. I know the documentation of Qt discourages using QThread::terminate but at the moment I do not see any other way.</p>
  
  <p>Below is a pseduo example of the code needed to run in a dedicated thread. There is basically one method which can take 10-15 minutes to process. There is no logical place to add moveToThread to take the affinity back to main thread on QThread::termination, or executiong processEvent to handle a QThread::quit() method.</p>
  
  <pre><code>void run()
  {
    // initiate variables
    thirdparty lib(var1, var2);
    int res = lib.execute(var3, var4, var6);
    // handle result and exit
  }
  </code></pre>
  
  <p>Using Qt 4.7 on Windows 7.</p>
  
  <p>Running the code produces this output</p>
  
  <pre><code>Test::doWork thread: QThread(0x219e960) 
  Test::started thread: QThread(0x239bce8)
  Test::doTerminate thread: QThread(0x239bce8) 
  Test::doWork thread: QThread(0x239bce8) 
  QObject::moveToThread: Current thread (0x219e960) is not the object's thread (0x239bce8). Cannot move to target thread (0x239bd20)
  </code></pre>
  
  <p>The moveToThread API fails on the second execution of the Test::doWork() method. This appears to be because the Test instance has affinity to another thread (which is terminated at this point). How can I then change the affinity?</p>
  
  <p>What is the recommended way to terminate and restart a QThread? Do I need to delete the Test instance?</p>
  
  <p>The code;</p>
  
  <pre><code>#include &lt;QCoreApplication&gt;
  #include &lt;QThread&gt;
  #include &lt;iostream&gt;
  #include &lt;QDebug&gt;
  #include "Worker.h"
  #include "Windows.h"
  
  class Test : public QObject
  {
    Q_OBJECT
    QThread* m_thread;
    int      m_state;
  
  public:
      Test() : m_thread(0), m_state(3) { }
  
  public slots:
      void doWork()
      {
        qDebug() &lt;&lt; "Test::doWork thread:" &lt;&lt; QObject::thread();
        if (!m_thread)
        {
          m_thread = new QThread();
          QObject::moveToThread(m_thread);
          QObject::connect(m_thread, SIGNAL(started()), this, SLOT(started()));
          QObject::connect(m_thread, SIGNAL(finished()), this, SLOT(finished()));
          QObject::connect(m_thread, SIGNAL(terminated()), this, SLOT(terminated()));
          m_thread-&gt;start();
        }
      }
  
      void started()
      {      
        qDebug() &lt;&lt; "Test::started thread:" &lt;&lt; QObject::thread();
        Sleep(60);
      }
  
      void finished()
      {
        qDebug() &lt;&lt; "Test::finished thread:" &lt;&lt; QObject::thread();
      }
  
      void terminated()
      {
        qDebug() &lt;&lt; "Test::terminated thread:" &lt;&lt; QObject::thread();
      }
  
      void doTerminate()
      {
        qDebug() &lt;&lt; "Test::doTerminate thread:" &lt;&lt; QObject::thread();
        QObject::disconnect(m_thread);
        m_thread-&gt;terminate();
        m_thread-&gt;wait();
        m_thread = NULL;
      }
  
      int state()
      {
        return m_state;
      }
  };
  
  int main(int argc, char *argv[])
  {
    QCoreApplication a(argc, argv);
    Test test;
  
    test.doWork();
    Sleep(10);
  
    test.doTerminate();
    Sleep(10);
  
    test.doWork();
    return a.exec();
  }
  </code></pre>