關于QT多線程開發介紹
-
QT下線程的建立方式
Qt中主要有兩種建立多線程的方式,一種是直接繼承QThread重寫run()函數來實作,另外一種是将一個繼承于QObject的普通類通過moveToThread()方法移動到一個線程裡去。 本文主要是理清如何正确的建立一個線程,和如何正确的退出一個線程。
本文主要記錄QThread的普通用法,網上有許多相關資料,如果已經了解可忽視,本文重點介紹線程安全退出的方法。
- 繼承QThread重寫run()函數線程建立方式
//.h檔案
class Mythread:public QThread
{
Q_OBJECT
public:
Mythread(){}
~ Mythread(){}
virtual void run();
/*******************/
};
/****************************/
//.cpp檔案
void Mythread::run()
{
while (1)
{
//耗時操作
}
}
- 繼承于QObject的普通類通過moveToThread()方法移動到一個線程的建立方式
//.h檔案
class Mythread:public QThread
{
Q_OBJECT
public:
Mythread(){}
~ Mythread(){}
virtual void run();
/*******************/
};
class MoveThread:public QObject
{
Q_OBJECT
public:
MoveThread(){}
~MoveThread(){}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
Mythread * m_thread;
MoveThread * m_movethread;
};
//.cpp檔案
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_thread= new Mythread ();
m_movethread= new MoveThread ();
m_movethread->moveToThread(m_thread);
}
二者建立線程的優缺點和差異在以後文章中會單獨列出(關于Qt多線程下信号槽的調用機制及事件循環機制的介紹)
-
QT線程開啟和退出
線程開啟函數:start()
不應該直接調用run函數,而應該使用**start()**函數
線程退出函數:quit()、exit()、terminate()用于線程終結退出
1.quit()函數告訴線程退出事件循環,讓exec()傳回0(成功)。等同于調用QThread::exit(0)。如果線程沒有事件循環,這個函數什麼事也不做。
2.exit()函數通知線程退出事件循環,并且傳入一個code值。
調用該函數後,線程退出事件循環,并從QEventLoop::exec()調用中傳回。QEventLoop::exec()傳回一個returnCode碼。一般情況,傳回碼為0意味着調用成功,非0值代表失敗。
注意:和c庫同名的函數不一樣,調用該函數不傳回一個值,它僅僅産生一個停止事件。
3.terminate()函數立即終止一個線程可以使用,但這個函數存在非常不安定因素,不推薦使用
4.線程調用wait()函數可以阻斷本身的運作,直到其他的線程完成執行(或者一個指定的時間間隔後)。
- 如何安全退出Qt線程
方法是添加一個bool變量,通過主線程修改這個bool變量來進行終止,但這樣有可能引起通路沖突,是以需要加鎖聯合使用。具體操作如下:
//.h檔案
class Mythread:public QThread
{
Q_OBJECT
public:
Mythread();
~Mythread();
virtual void run();
void runstart()
{
isCanRun=true;
}
void runstop()
{
isCanRun=false;
}
bool getcurrentstate()
{
return isCanRun;
}
/**********變量區**********/
protected:
volatile bool isCanRun = false;
public slots:
void stopImmediatelyS1();
private:
static QMutex m_lock; //原子操作鎖
/*******************/
};
//.cpp檔案
Mythread::Mythread()
{
isCanRun = false;
connect(this,SIGNAL(finished()),this,SLOT(deleteLater()));
}
QMutex Mythread::m_lock; //初始化靜态鎖
Mythread::~Mythread()
{
}
void Mythread::stopImmediatelyS1()
{
QMutexLocker locker(&m_lock);
isCanRun = false;
}
void Mythread::run()
{
isCanRun = true;
while (isCanRun)
{
//耗時操作
{
QMutexLocker locker(&m_lock);
if(!isCanRun) //設定退出線程
{
return;
}
}
exec();//開啟事件循環
}
}
這裡是引用:本文是個人開發學習記錄,如有差錯歡迎大神指點