前置:
主執行緒:UI執行緒,視窗事件處理,視窗控制元件資料更新。
子執行緒:後臺業務處理,子執行緒不對視窗物件做任何處理,這些事情交給主執行緒
主執行緒,子執行緒進行資料傳遞使用訊號槽
QThread
QThread Class 屬於core. 父QObjecr
一些方法
常用成員函式:
QThread::QThread(QObject * parent = Q_NULLPTR);//引數為父物件,物件樹,資源清理
bool QThread::isFinished() const;//判斷執行緒任務是否處理完畢
bool QThread::isRunning() const;//判斷執行緒是否在執行任務
Priority QThread::priority() const;//讀取優先順序
void QThread::setPriority(Priority priority);//設定優先順序
void QThread::exit(int returnCode = 0);//執行緒退出,直接退(後續還有部分資源處理)
bool QThread::wait(unsigned long time = ULONG_MAX);//執行緒退出,等待任務完成
訊號槽
槽函式:
void QThread::quit();//和exit效果一樣,之後在呼叫wait()
void QThread::start(Priority priority = InheritPriority);//啟動子執行緒
void QThread::terminate();//直接終止執行緒
訊號:
void QThread::finished();//執行緒任務執行完畢發出
void QThread::started();//執行緒開始工作前發出
靜態函式:
QThread *QThread::currentThread();//返回一個指向當前管理執行緒的指標。
int QThread::idealThreadCount();//在當先系統上執行的理想執行緒數,即cpu核心數
void QThread::msleep(unsigned long);//休眠
void QThread::sleep(unsigned long);//休眠
void QThread::usleep(unsigned long);//休眠
任務處理函式(virtual protected型別)
void QThread::run();//子類繼承並重寫,透過start()啟動
使用:
第一種:
1.建立子類,繼承QThread類
2.重寫run方法
3.主執行緒中建立子執行緒物件
舉例:MyThread * sunThread = new MyThread;
4.啟用start()方法,啟動子執行緒。
注:
*子執行緒建立出來後,父子間通訊可以使用訊號槽方式
*Qt中,子執行緒不要操作程式中的視窗型別物件,不允許,操作了程式就掛了
*主執行緒才能操作視窗型別物件
第二種:
1.建立子類,繼承QObject類
2.在該類中新增公共的成員函式,作為子執行緒的業務邏輯。
舉例:
public:
void working();
3.在主執行緒中建立一個QThread物件(這就是子執行緒的物件)
舉例:
QThread * sub = new QThread;
4.在主執行緒中建立工作的類物件(不要給建立的物件指定父物件)
舉例:
MyThread * work = new MyWork(this);//error
MyThread * work = new MyWork();
5.將工作類的物件移動到建立的子執行緒物件中,需要呼叫QObject類提供的moveToThread()方法
舉例:
work->moveToThread(sub);//如果給work指定了父物件,就呼叫失敗
6.啟動子執行緒,呼叫start(),這時候執行緒啟動,但是移動到執行緒內的物件並沒有開始工作。
7.呼叫MyWork類對向的工作函式,讓這個函式開始執行,這時候是在移動到的那個子執行緒中執行的。
注:
執行緒資源銷燬:
第一種:建立執行緒物件時指定父物件(物件樹)
第二種:檢測主執行緒的析構訊號
舉例:
connect(this, &MainWindow::destroy, this, [=](){
t1->quit();
t1->wait();
t1->deleteLater();//封裝了delete t1;
}
執行緒池的使用:
QThreadPool:
//獲取和設定執行緒池中的最大執行緒個數:
int maxThreadCount() const;
void setMaxThreadCount(int maxThreadCount);
//給執行緒池新增任務,為QRunnable型別
//如果執行緒池中沒有空閒執行緒了,任務會放到任務佇列中,等待執行緒處理
void QThreadPool::start(QRunnable * runnable, int priority = 0);
bool QThreadPool::tryStart(QRunnable * runnable);//如果執行緒池中沒有空閒執行緒了,任務新增失敗,不會新增到任務佇列
int QThreadPool::activeThreadCount() const;//正在工作的執行緒個數
bool QThreadPool::tryTake(QRunnable * runnable);//嘗試刪除執行緒池中的某個任務,如果任務已經開始,則無法刪除
void QThreadPool::clear();//刪除執行緒池中所有沒有開始的任務
static QThreadPool* QThreadPool::globalInstance();//獲取執行緒池的全域性物件
QRunnable(執行緒池的任務物件類):
(純虛)void QRunnable::run();//任務的執行流程,必須重寫
void QRunnable::setAutoDelete(bool autoDelete);//設定執行緒任務結束後,任務物件是否自動銷燬。
bool QRunnable::autoDelete() const;//獲取任務物件的析構方式,是否自動銷燬
注:
設定自動銷燬後,無需在手動釋放執行緒物件資源