1

この例は、QThread をテストするためのものです。主な目的は、時間のかかるブロッキング メソッドを専用スレッドで 1 回実行できるようにし、いつでもスレッドを終了して再起動できるようにすることです。ブロック方法は、私たちの管理外にあるサードパーティのライブラリです。Qt のドキュメントで QThread::terminate の使用が推奨されていないことは知っていますが、現時点では他の方法は見当たりません。

以下は、専用スレッドで実行するために必要なコードの疑似例です。基本的に、処理に 10 ~ 15 分かかる方法が 1 つあります。QThread::termination でアフィニティをメイン スレッドに戻すために moveToThread を追加したり、QThread::quit() メソッドを処理するために processEvent を実行したりする論理的な場所はありません。

void run()
{
  // initiate variables
  thirdparty lib(var1, var2);
  int res = lib.execute(var3, var4, var6);
  // handle result and exit
}

Windows 7 で Qt 4.7 を使用しています。

コードを実行すると、この出力が生成されます

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)

moveToThread API は、Test::doWork() メソッドの 2 回目の実行で失敗します。これは、Test インスタンスが別のスレッド (この時点で終了) にアフィニティを持っているためと思われます。アフィニティを変更するにはどうすればよいですか?

QThread を終了して再起動するための推奨される方法は何ですか? テスト インスタンスを削除する必要がありますか?

コード;

#include <QCoreApplication>
#include <QThread>
#include <iostream>
#include <QDebug>
#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() << "Test::doWork thread:" << 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->start();
      }
    }

    void started()
    {      
      qDebug() << "Test::started thread:" << QObject::thread();
      Sleep(60);
    }

    void finished()
    {
      qDebug() << "Test::finished thread:" << QObject::thread();
    }

    void terminated()
    {
      qDebug() << "Test::terminated thread:" << QObject::thread();
    }

    void doTerminate()
    {
      qDebug() << "Test::doTerminate thread:" << QObject::thread();
      QObject::disconnect(m_thread);
      m_thread->terminate();
      m_thread->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();
}
4

1 に答える 1

0

terminate を使用する代わりに、より受け入れやすい関数 quit() を呼び出すことができます。

于 2013-10-30T13:55:58.240 に答える