這個例子用於測試QThread。主要目標是能夠在專用線程中運行耗時的阻塞方法,並且可以在任何時候終止並重新啓動線程。阻塞方法是第三方庫,這是我們無法控制的。我知道Qt阻止使用QThread :: terminate的文檔,但目前我沒有看到任何其他方式。QThread終止和親和力
下面是在專用線程中運行所需代碼的一個示例。基本上有一種方法可能需要10-15分鐘來處理。沒有合適的地方添加moveToThread,以便將親和力帶回到QThread :: termination的主線程,或者執行processEvent來處理QThread :: quit()方法。
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在試驗的第二執行失敗::的doWork()方法。這似乎是因爲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();
}
在殺死m_thread之前,你可以將'Test'對象返回主線程,但這似乎有點奇怪。如果你不得不重新開始,爲什麼要殺死線程? – thuga
你也應該考慮把'm_thread' ['finished()'](http://qt-project.org/doc/qt-5.0/qtcore/qthread.html#finished)信號連接到它的['deleteLater ()'](http://qt-project.org/doc/qt-5.0/qtcore/qobject.html#deleteLater)插槽。現在你將'm_thread'值設置爲'0',但是我沒有看到你在任何地方摧毀了這個對象。 – thuga
第三方方法使用許多參數執行。如果參數不正確,您可能想要終止執行,然後用不同的參數重新啓動。 – Lars