日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt中线程的简单使用

發(fā)布時(shí)間:2024/9/27 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt中线程的简单使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

對(duì)于線程過去寫的比較少,現(xiàn)在也幾乎是小白的水平。先創(chuàng)建Qt empty project,即Qt空項(xiàng)目,打開QtCreate->文件->新建文件或項(xiàng)目->其它項(xiàng)目->empty qmke project,接著按提示創(chuàng)建Qt空項(xiàng)目,創(chuàng)建之后,在項(xiàng)目上右鍵添加新文件,選擇源文件,創(chuàng)建main.cpp文件,添加如下代碼:
main.cpp

#include <QtCore>int main(int argc,char* argv[]) {QCoreApplication app(argc,argv);return app.exec(); }

再添加新文件,選擇類,基類為QThread,類名為myThread,最后添加代碼后文件內(nèi)容為:
myThread.h

#ifndef MYTHREAD_H #define MYTHREAD_H#include <QThread>class myThread : public QThread {Q_OBJECT public:explicit myThread(QObject *parent = nullptr); protected:void run(); private: // volatile bool stopped; };#endif // MYTHREAD_H

myThread.cpp

#include "mythread.h" #include "Counter.h" #include <QDebug>myThread::myThread(QObject *parent):QThread(parent) { // stopped = false; }void myThread::run() {Counter counter;quint8 i = 4;while(i--){counter.increment(); // int n = counter.GetValue(); // qDebug()<<QString("n:").arg(counter.GetValue());qDebug()<<"n:"<<counter.GetValue();} }

再添加另一個(gè)線程類,同樣在項(xiàng)目上右鍵添加新文件,選擇類,類名mythreadread,基類為QThread,創(chuàng)建好這個(gè)類之后,添加完代碼之后,文件內(nèi)容如下:
mythreadread.h

#ifndef MYTHREADREAD_H #define MYTHREADREAD_H#include <QThread>class mythreadread : public QThread {Q_OBJECT public:explicit mythreadread(QObject *parent = nullptr); protected:void run(); };#endif // MYTHREADREAD_H

mythreadread.cpp

#include "mythreadread.h" #include "Counter.h" #include <QDebug>mythreadread::mythreadread(QObject *parent):QThread(parent) {}void mythreadread::run() {Counter counter;quint8 i = 4;while(i--){counter.decrement();qDebug()<<"n="<<counter.GetValue();} }

以上兩個(gè)線程類創(chuàng)建完成之后,在項(xiàng)目上右鍵添加新文件Counter.h,即添加頭文件,添加之后,修改其代碼如下:
Counter.h

#ifndef COUNTER_H #define COUNTER_Hclass Counter { public:Counter():n(0){}void increment(){n++;}void decrement(){n--;}int GetValue()const{return n;}//該函數(shù)不能修改類成員變量的值 private:int n; }; #endif // COUNTER_H

現(xiàn)在在main函數(shù)中修改代碼如下:
main.cpp

#include <QtCore> #include "mythread.h" #include "mythreadread.h"myThread thread1; mythreadread thread2;int main(int argc,char* argv[]) {QCoreApplication app(argc,argv);//針對(duì)各自線程中的特定對(duì)象的成員操作,互不影響thread1.start();thread1.wait();thread2.start();thread2.wait();return app.exec(); }

運(yùn)行程序,結(jié)果如下:
n: 1
n: 2
n: 3
n: 4
n= -1
n= -2
n= -3
n= -4
結(jié)論:第一個(gè)線程啟動(dòng)后,在其線程函數(shù)中創(chuàng)建了Counter的類對(duì)象,并循環(huán)調(diào)用四次Counter類的加計(jì)數(shù)函數(shù),然后輸出每一次加計(jì)數(shù)后的值,最后調(diào)用wait()函數(shù)等待線程的結(jié)束,第一個(gè)線程結(jié)束之后,啟動(dòng)第二個(gè)線程,在該線程中對(duì)Counter類的成員變量減計(jì)數(shù),并輸出每一次減計(jì)數(shù)后的值,最后等帶線程二結(jié)束之后,主程序關(guān)閉。其中有三個(gè)點(diǎn)需要注意:

  • 在Counter類的定義中,將函數(shù)的聲明與定義放在了同一個(gè)文件Counter.h中。需要注意的是,在同一個(gè)文件中定義并聲明一個(gè)類時(shí),函數(shù)的定義不能在該類外,否則會(huì)出現(xiàn)錯(cuò)誤提示,重定義該文件。像下面所寫一樣:
  • #ifndef COUNTER_H #define COUNTER_Hclass Counter { public:Counter():n(0){}int GetValue(); private:int n; }; void Counter::GetValue() {return n; } #endif // COUNTER_H

    這樣在類中定義成員函數(shù),會(huì)導(dǎo)致編譯錯(cuò)誤,只能在類中進(jìn)行定義。

    #ifndef COUNTER_H #define COUNTER_Hclass Counter { public:Counter():n(0){}int GetValue(){return n;} private:int n; };#endif // COUNTER_H
  • 引入可重入的概念,一個(gè)類可以被多個(gè)線程使用,但每一次只能是調(diào)用該類自己的成員函數(shù)或成員變量。上面兩個(gè)線程,在run()函數(shù)中分別對(duì)Counter類的成員函數(shù)進(jìn)行操作,針對(duì)的是每一個(gè)Counter類自己的成員函數(shù)的操作,所以兩個(gè)線程之間沒有涉及到數(shù)據(jù)共享,線程同步等問題,可以線程實(shí)際是獨(dú)立的。
  • 如果將main.cpp中主函數(shù)中的兩個(gè)線程的啟動(dòng)順序變?yōu)槿缦?#xff1a;
  • thread1.start();thread2.start();thread1.wait(); thread2.wait();

    那么程序的運(yùn)行結(jié)果是怎么樣呢?其運(yùn)行結(jié)果如下:
    n: 1
    n= -1
    n: 2
    n= -2
    n: 3
    n= -3
    n: 4
    n= -4
    可以看出,兩個(gè)線程幾乎是同時(shí)運(yùn)行的,他們之間并行運(yùn)行各自的run()函數(shù),在對(duì)Counter類操作時(shí),n的初始值都是從0開始,互不影響。
    附加總結(jié):
    創(chuàng)建線程的方法之一是創(chuàng)建一個(gè)繼承自QThread的類,引入#include頭文件,在類的聲明的開頭加入Q_OBJECT宏,在類中重寫run()函數(shù),在類定義中對(duì)run()函數(shù)進(jìn)行定義,即線程需要做的事情在run()函數(shù)中編寫,線程類便創(chuàng)建完成了。線程調(diào)用時(shí)引入線程所在類的頭文件,在需要線程的地方,定義線程對(duì)象,并調(diào)用start()函數(shù)啟動(dòng)線程,線程結(jié)束的地方可以調(diào)用stop()函數(shù)停止線程,但在之前最好加上wait()函數(shù)等待線程的結(jié)束。

    terminate的說明

    terminate并不會(huì)立即終止線程,它取決于系統(tǒng)的調(diào)度,此外調(diào)用這個(gè)函數(shù)時(shí)最好在其后調(diào)用一下wait()函數(shù)等待線程結(jié)束,但是terminate()存在危險(xiǎn)性,因?yàn)闊o法知道它在何時(shí)會(huì)關(guān)閉線程,而且關(guān)閉線程時(shí)不會(huì)做清理工作,盡量少用。

    總結(jié)

    以上是生活随笔為你收集整理的Qt中线程的简单使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。