淺析 Qt中多線程系列之線程控制 下篇
Qt中多線程系列之線程控制是本文要介紹的內(nèi)容,上回講到線程的初步使用, 淺析 Qt中多線程系列之線程初體驗(yàn) 上篇 寫(xiě)了個(gè)線程的創(chuàng)建到運(yùn)行的過(guò)程,可這還沒(méi)完,線程創(chuàng)建完了之后必須要對(duì)其進(jìn)行限制和控制,我們就是線程的監(jiān)護(hù)人,不能說(shuō)任由它自由,得對(duì)它進(jìn)行合理約束。接下來(lái)我們講線程的控制部分,
1、線程休眠
想象一下一種情形,日常用的電腦,如果我們需要離開(kāi)一段時(shí)間,那么可能會(huì)將它暫時(shí)休眠一下,為了節(jié)約用電,也響應(yīng)一下環(huán)境保護(hù),別忘了現(xiàn)在都講低炭生活。那么線程其實(shí)也一樣,如果一個(gè)線程暫時(shí)不需要用到,我們可以先讓它睡會(huì),其目的也是為了讓它暫時(shí)不要占用資源,主要是一個(gè)cpu時(shí)間片的占用問(wèn)題。
對(duì)于線程的休眠,只要簡(jiǎn)單調(diào)用 Qthread 的sleep ,msleep或者usleep 方法就可以了,注意這三個(gè)方法都是Static Protected的,這意味著你只能在繼承類(lèi)里做這個(gè)動(dòng)作,它們差別僅是時(shí)間單位不同而已。
程序方面我們盡量簡(jiǎn)單點(diǎn),能看清本質(zhì)就可以了,在Qthread 派生類(lèi)的Run方法里面用下
- void CThread::run()
- {
- for(int i=1;i<=10000;i++)
- {
- qDebug()<<i;
- sleep(1); //請(qǐng)不要那么快,睡一下再往下執(zhí)行
- }
- }
2、線程喚醒
既然有線程的休眠,那就有喚醒。如果你已經(jīng)和線程說(shuō) Sleep 10秒吧,突然人家睡到一半的時(shí)候,你又改變主意想讓它醒過(guò)來(lái),這里我要抱歉的說(shuō)聲是沒(méi)辦法的,它就像豬一樣,沒(méi)到時(shí)間是不會(huì)醒的。比較合適的方案就是線程同步能夠解決這樣的問(wèn)題,這個(gè)放到 下一篇 線程的同步[1/2] 的時(shí)候再說(shuō).只要記住sleep是強(qiáng)制休眠就可以,但現(xiàn)在沒(méi)辦法提供強(qiáng)制喚醒的辦法.
3、線程關(guān)閉
如果一個(gè)線程運(yùn)行完了它會(huì)自己結(jié)束自己的生命??珊芏嗲闆r不是這么簡(jiǎn)單,一個(gè)線程跑到中間的時(shí)候由于某種特殊原因,就想它中止。
(1)線程中止方式
中止有兩種方式 強(qiáng)制中止和 優(yōu)雅中止,這用詞可能有點(diǎn)不恰當(dāng),先這么說(shuō)著。在說(shuō)明這兩種方式之前,有必要詳細(xì)說(shuō)一下線程關(guān)閉的時(shí)候它到底干了什么。
線程關(guān)閉的時(shí)候,OS會(huì)移除這個(gè)線程,這部分對(duì)我們是透明的,詳細(xì)的說(shuō)明還得參閱操作系統(tǒng)的有關(guān)書(shū)籍,接著線程中分配的堆棧信息將一并清除,但是如果是堆上分配的信息,得由你負(fù)責(zé)自己清除,因?yàn)槎咽怯蛇M(jìn)程持有的,它的生命周期和線程沒(méi)關(guān)系。
(2)強(qiáng)制中止:
簡(jiǎn)單的調(diào)用Qthread 的方法terminate就可以進(jìn)行強(qiáng)制中止,可這將會(huì)帶來(lái)很多災(zāi)難性的后果。最為嚴(yán)重的就是一個(gè)堆內(nèi)存泄露的問(wèn)題,線程強(qiáng)制被中止,根本沒(méi)法來(lái)得及做清理工作,即使你的線程 中有執(zhí)行到最后清理堆內(nèi)存,可它沒(méi)來(lái)得及執(zhí)行
比如以下一段代碼
- void CThread::run()
- {
- int *c = new int;
- for(int i=1;i<=10000;i++)
- {
- qDebug()<<i;
- }
- //clean
- delete c;
- }
想象一下線程還沒(méi)執(zhí)行 到 delete c;的時(shí)候你就發(fā)出了terminate,不幸的事就發(fā)生了,由此得出結(jié)論我們應(yīng)該盡最大限度避免去使用。
(3)優(yōu)雅的中止:
那么怎么優(yōu)雅的關(guān)閉線程呢?我們應(yīng)該通知線程,讓線程自己去接手關(guān)閉,各自關(guān)注自己所需的事,就都能做得更好,一手抓就會(huì)帶來(lái)很多問(wèn)題
那么怎么通知線程呢? 一般會(huì)采用以下的步驟
1.在Qthread中派生類(lèi) 定義一個(gè)公用方法出來(lái) 供中止時(shí)調(diào)用,比如stop()
2.調(diào)用者 直接 調(diào)用stop方法
3.派生類(lèi)stop方法 ,設(shè)置 中止標(biāo)志,一般就是bool成員
4.run方法 運(yùn)行的時(shí)候,檢查bool成員,判斷是否需要退出進(jìn)程,最后做清理工作
- //CThread.h
- #ifndef CTHREAD_H
- #define CTHREAD_H
- #include <QThread>
- class CThread : public QThread
- {
- public:
- CThread();
- ~CThread();
- void stop();
- protected:
- void run();
- private:
- bool mStop;
- };
- #endif // CTHREAD_H
- //CThread.cpp
- #include <QDebug>
- #include "CThread.h"
- CThread::CThread():QThread(),mStop(false)
- {
- }
- CThread::~CThread()
- {
- stop();
- }
- void CThread::run()
- {
- int *c = new int;
- for(int i=1;i<=10000;i++)
- {
- if (mStop) // determine to exit the loop
- {
- break;
- }
- qDebug()<<i;
- sleep(1);
- }
- //clean up
- delete c;
- }
- void CThread::stop()
- {
- mStop = true;
- wait();
- }
小結(jié):關(guān)于Qt中多線程系列之線程控制 下篇的內(nèi)容介紹完了,也可參考 淺析 Qt中多線程系列之線程初體驗(yàn) 上篇 ,最后希望本文對(duì)你有所幫助。