首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Qt 多線程程式設計完全指南:從基礎到生產者消費者模型實戰

     編輯:Java 綜合教學

核心概念釐清

術語定義
進程資源分配最小單位,擁有獨立記憶體空間
線程CPU 調度最小單位,共享進程資源
並發宏觀同時、微觀輪流(單核分時)
並行多核真正同時執行
同步阻止有依賴關係的操作同時發生
異步獨立操作互不阻塞、各自進行

Qt 線程基礎:繼承 QThread

class MyThread : public QThread {
    Q_OBJECT
public:
    MyThread() : stopped(false) {}
    void stop() { stopped = true; }
protected:
    void run() override {
        int i = 0;
        while (!stopped) {
            qDebug() << "thread id:" << QThread::currentThreadId() << ":" << i++;
            sleep(2);
        }
        stopped = false;
    }
private:
    volatile bool stopped;
};

關鍵點:start() 啟動線程並自動呼叫 run();isRunning() 判斷狀態;terminate() 強制結束(不推薦常用)。

線程同步三大工具

1. 信號量 — QSemaphore

控制有限資源存取,acquire() 取資源、release() 釋放。生產者-消費者經典範例:

QSemaphore freeBytes(100), usedBytes(0);

void Producer::run() {
    for (int i=0; i<100; ++i) {
        freeBytes.acquire();      // 等待空位
        produce(i);
        usedBytes.release();      // 通知有資料
    }
}
void Consumer::run() {
    for (int i=0; i<100; ++i) {
        usedBytes.acquire();      // 等待資料
        consume(i);
        freeBytes.release();      // 歸還空位
    }
}

2. 條件變量 — QWaitCondition + QMutex

等待特定條件成立,避免忙等待:

QMutex mutex;
QWaitCondition notFull, notEmpty;
int buffer[50], used = 0;

void Producer::run() {
    for (int i=0; i<50; ++i) {
        mutex.lock();
        if (used == 50) notFull.wait(&mutex); // 釋放鎖並等待
        buffer[used++] = i;
        qDebug() << "produce" << i;
        notEmpty.wakeAll();                   // 喚醒消費者
        mutex.unlock();
        sleep(1);
    }
}
void Consumer::run() {
    for (int i=0; i<50; ++i) {
        mutex.lock();
        if (used == 0) notEmpty.wait(&mutex);
        qDebug() << "consume" << buffer[--used];
        notFull.wakeAll();
        mutex.unlock();
        sleep(2);
    }
}

3. 互斥鎖 — QMutex

保護臨界區,lock()/unlock() 或配合 QMutexLocker 自動解鎖(RAII)。

線程優先級控制

thread->start(QThread::HighPriority);  // 啟動時指定
thread->setPriority(QThread::LowPriority); // 運行中調整

優先級僅為調度提示,具體行為視作業系統而定。

Qt 線程間通信最佳實踐

  • 訊號與槽:跨線程自動排隊(QueuedConnection),線程安全零成本
  • 事件迴路:Worker 線程若需接收事件,必須執行 exec()
  • 避免直接操作 UI:UI 物件只能在主線程存取,背景線程透過訊號傳遞資料

常見陷阱提醒

  1. volatile bool stopped 只能防編譯器優化,**不能**保證多核可見性,正式專案請用 QAtomicInt 或 std::atomic
  2. sleep() 在 run() 中會阻塞事件迴路,需定時處理事件請用 QTimer 或 QEventLoop
  3. 線程結束前務必 quit() + wait() 確保資源釋放

掌握 Qt 多線程核心機制,善用訊號槽解耦、同步原語護航,即能編寫高效穩定的併發應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved