QT学习:多线程
一、優勢。
(1)提高應用程序的響應速度。這對于開發圖形界面的程序尤為重要,當一個操作耗時很長時,整 個系統都會等待這個操作,程序就不能響應鍵盤、鼠標、菜單等的操作,而使用多線程技術可將耗時長的 操作置于一個新的線程,從而避免出現以上問題。
 (2)使多CPU系統更加有效。當線程數不大于CPU數目時,操作系統可以調度不同的線程運行于不同 的CPU上。
 (3)改善程序結構。一個既長又復雜的進程可以考慮分為多個線程,成為獨立或半獨立的運行部分, 這樣有利于代碼的理解和維護。
二、特點
(1)多線程程序的行為無法預期,當多次執行上述程序時,每次的運行結果都可能不同。
 (2)多線程的執行順序無法保證,它與操作系統的調度策略和線程優先級等因素有關。
 (3)多線程的切換可能發生在任何時刻、任何地點。
 (4)由于多線程對代碼的敏感度高,因此對代碼的細微修改都可能產生意想不到的結果。
三、簡單實例
單擊“開始”按鈕將啟動數個工作線程(工作線程 數目由MAXSIZE宏決定),各個線程循環打印數字0~9,直到單擊“停止”按鈕終止所有線程為止。具體操作步驟如下:
 (1)在頭文件“threaddlg.h”中聲明用于界面顯示所需的控件,其具體代碼如下:
(2)在源文件“threaddlg.cpp”的構造函數中,完成各個控件的初始化工作,其具體代碼如下:
#include "threaddlg.h" #include <QHBoxLayout> ThreadDlg::ThreadDlg(QWidget *parent) : QDialog(parent) { setWindowTitle(tr("線程")); startBtn = new QPushButton(tr("開始")); stopBtn = new QPushButton(tr("停止")); quitBtn = new QPushButton(tr("退出")); QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->addWidget(startBtn); mainLayout->addWidget(stopBtn); mainLayout->addWidget(quitBtn); }(3)此時運行程序,界面顯示如下圖所示:
 
以上完成了界面的設計,下面的內容是具體的功能實現。
 (1)在頭文件“workthread.h”中,工作線程WorkThread類繼承自QThread類。重新實現run()函數。其具體代碼如下:
(2)在源文件“workthread.cpp”中添加具體實現代碼如下:
#include "workthread.h" #include <QtDebug> WorkThread::WorkThread() { }run()函數實際上是一個死循環,它不停地打印數字0~9。為了顯示效果明顯,程序將每一個數字重復打印8次。
void WorkThread::run() { while(true) { for(int n=0;n<10;n++) qDebug()<<n<<n<<n<<n<<n<<n<<n<<n; } }(3)在頭文件“threaddlg.h”中添加以下內容:
#include "workthread.h" #define MAXSIZE 1 //MAXSIZE宏定義了線程的數目 public slots: void slotStart(); //槽函數用于啟動線程 void slotStop(); //槽函數用于終止線程 private: WorkThread *workThread[MAXSIZE]; //(a) 指向工作線程(WorkThread)的私有指針數組workThread,記錄了所啟動的全部線程。(4)在源文件“threaddlg.cpp”中添加以下內容。
 在構造函數中添加如下代碼:
當用戶單擊“開始”按鈕時,將調用槽函數slotStart()。這里使用兩個循環,目的是使新建的線程盡可能同時開始執行,其具體實現代碼如下:
void ThreadDlg::slotStart() { for(int i=0;i<MAXSIZE;i++) { workThread[i]=new WorkThread(); //創建指定數目的WorkThread線程,并將WorkThread實例的指針保存在指針數組workThread中。 } for(int i=0;i<MAXSIZE;i++) { workThread[i]->start(); //(b) 調用QThread基類的start()函數,此函數將啟動run()函數,從而使線程開始真正運行。 } startBtn->setEnabled(false); stopBtn->setEnabled(true); }當用戶單擊“停止”按鈕時,將調用槽函數slotStop()。其具體實現代碼如下:
void ThreadDlg::slotStop() { for(int i=0;i<MAXSIZE;i++) { workThread[i]->terminate(); workThread[i]->wait(); } startBtn->setEnabled(true); stopBtn->setEnabled(false); }(5)多線程簡單實現結果如下圖所示。
 
 
第1張圖片是啟動5個線程的運行結果,第2張圖片是啟動單一線程的運行結果。可以看出,單一線程的輸出是順序打印的,而多線程的輸出結果則是亂序打印的,這正是多線程的一大特點。
總結
 
                            
                        - 上一篇: QT学习:事件过滤
- 下一篇: QT学习:多线程控制
