<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                #():線程簡介 前面我們討論了有關進程以及進程間通訊的相關問題,現在我們開始討論線程。事實上,現代的程序中,使用線程的概率應該大于進程。特別是在多核時代,隨著 CPU 主頻的提升,受制于發熱量的限制,CPU 散熱問題已經進入瓶頸,另辟蹊徑地提高程序運行效率就是使用線程,充分利用多核的優勢。有關線程和進程的區別已經超出了本章的范疇,我們簡單提一句,一個進程可以有一個或更多線程同時運行。線程可以看做是“輕量級進程”,進程完全由操作系統管理,線程即可以由操作系統管理,也可以由應用程序管理。 Qt?使用`QThread`?來**管理**線程。下面來看一個簡單的例子: ~~~ ///!!! Qt5 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QWidget *widget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout; widget->setLayout(layout); QLCDNumber *lcdNumber = new QLCDNumber(this); layout->addWidget(lcdNumber); QPushButton *button = new QPushButton(tr("Start"), this); layout->addWidget(button); setCentralWidget(widget); QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, [=]() { static int sec = 0; lcdNumber->display(QString::number(sec++)); }); WorkerThread *thread = new WorkerThread(this); connect(button, &QPushButton::clicked, [=]() { timer->start(1); for (int i = 0; i < 2000000000; i++); timer->stop(); }); } ~~~ 我們的主界面有一個用于顯示時間的 LCD 數字面板還有一個用于啟動任務的按鈕。程序的目的是用戶點擊按鈕,開始一個非常耗時的運算(程序中我們以一個 2000000000 次的循環來替代這個非常耗時的工作,在真實的程序中,這可能是一個網絡訪問,可能是需要復制一個很大的文件或者其它任務),同時 LCD 開始顯示逝去的毫秒數。毫秒數通過一個計時器`QTimer`進行更新。計算完成后,計時器停止。這是一個很簡單的應用,也看不出有任何問題。但是當我們開始運行程序時,問題就來了:點擊按鈕之后,程序界面直接停止響應,直到循環結束才開始重新更新。 有經驗的開發者立即指出,這里需要使用線程。這是因為 Qt?中所有界面都是在 UI?線程中(也被稱為主線程,就是執行了`QApplication::exec()`的線程),在這個線程中執行耗時的操作(比如那個循環),就會阻塞 UI?線程,從而讓界面停止響應。界面停止響應,用戶體驗自然不好,不過更嚴重的是,有些窗口管理程序會檢測到你的程序已經失去響應,可能會建議用戶強制停止程序,這樣一來你的程序可能就此終止,任務再也無法完成。所以,為了避免這一問題,我們要使用 QThread?開啟一個新的線程: ~~~ ///!!! Qt5 class WorkerThread : public QThread { Q_OBJECT public: WorkerThread(QObject *parent = 0) : QThread(parent) { } protected: void run() { for (int i = 0; i < 1000000000; i++); emit done(); } signals: void done(); }; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QWidget *widget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout; widget->setLayout(layout); lcdNumber = new QLCDNumber(this); layout->addWidget(lcdNumber); QPushButton *button = new QPushButton(tr("Start"), this); layout->addWidget(button); setCentralWidget(widget); QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, [=]() { static int sec = 0; lcdNumber->display(QString::number(sec++)); }); WorkerThread *thread = new WorkerThread(this); connect(thread, &WorkerThread::done, timer, &QTimer::stop); connect(thread, &WorkerThread::finished, thread, &WorkerThread::deleteLater); connect(button, &QPushButton::clicked, [=]() { timer->start(1); thread->start(); }); } ~~~ 注意,我們增加了一個`WorkerThread`類。`WorkerThread`繼承自`QThread`類,重寫了其`run()`函數。我們可以認為,`run()`函數就是新的線程需要執行的代碼。在這里就是要執行這個循環,然后發出計算完成的信號。而在按鈕點擊的槽函數中,使用`QThread::start()`函數啟動一個線程(注意,這里不是`run()`函數)。再次運行程序,你會發現現在界面已經不會被阻塞了。另外,我們將`WorkerThread::deleteLater()`函數與`WorkerThread::finished()`信號連接起來,當線程完成時,系統可以幫我們清除線程實例。這里的`finished()`信號是系統發出的,與我們自定義的`done()`信號無關。 這是 Qt?線程的最基本的使用方式之一(確切的說,這種使用已經不大推薦使用,不過因為看起來很清晰,而且簡單使用起來也沒有什么問題,所以還是有必要介紹)。代碼看起來很簡單,不過,如果你認為 Qt 的多線程編程也很簡單,那就大錯特錯了。Qt?多線程的優勢設計使得它使用起來變得容易,但是坑很多,稍不留神就會被絆住,尤其是涉及到與 QObject 交互的情況。稍懂多線程開發的童鞋都會知道,調試多線程開發簡直就是煎熬。下面幾章,我們會更詳細介紹有關多線程編程的相關內容。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看