この例は、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();
}