在多線程開發中,經常需要控制多個線程對共享資源的訪問數量。例如限制同時下載文件的數量、控制數據庫連接池的連接使用等等。這時候,Qt 提供的 QSemaphore
(信號量)就非常派得上用場。
一、什么是 QSemaphore?
QSemaphore
是 Qt 中提供的一種線程同步工具。它通過內部維護一個資源計數器,允許多個線程同時訪問共享資源,但訪問數量受到限制。
它與互斥鎖(QMutex
)的區別在于:
QMutex
是互斥的,每次只允許一個線程進入臨界區。QSemaphore
是限量的,可以允許多個線程同時訪問資源,但不會超過指定的最大數量。
可以把 QSemaphore
想象成一個“通行證發放器”:資源有限,有票的線程才能進入,無票的線程就只能等著。
二、典型應用場景
- 同時最多只允許 N 個線程運行某項任務(例如下載器中最多允許 3 個并發下載)
- 限制線程池中可用線程的最大數
- 實現生產者-消費者模式中的緩沖區容量限制
- 控制數據庫連接池的并發訪問數量
總之,任何需要限制并發訪問數量的場景,QSemaphore
都能派上用場。
三、常用方法說明
方法名 | 說明 |
---|---|
acquire(int n = 1) | 申請 n 個資源,不足則阻塞線程,直到資源可用 |
release(int n = 1) | 釋放 n 個資源,通知其他等待的線程 |
tryAcquire(int n = 1) | 嘗試申請 n 個資源,如果資源不足,立即返回 false |
available() | 獲取當前可用的資源數量 |
四、實戰案例:限制同時運行線程數
目標說明
創建 10 個線程,每個線程執行一項任務。但系統最多只允許 3 個線程同時執行,其余線程必須等待已有線程完成任務后再開始執行。
C++ 代碼示例(基于 Qt)
#include <QCoreApplication>
#include <QThread>
#include <QSemaphore>
#include <QDebug>// 最大并發線程數設為 3
const int MAX_CONCURRENT = 3;
QSemaphore semaphore(MAX_CONCURRENT);// 自定義線程類
class Worker : public QThread
{int id;public:Worker(int id) : id(id) {}void run() override {// 申請資源,如果不足會阻塞semaphore.acquire();qDebug() << "線程" << id << "開始執行任務...";// 模擬任務耗時QThread::sleep(2);qDebug() << "線程" << id << "任務完成!";// 釋放資源semaphore.release();}
};int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QList<Worker*> workers;// 啟動 10 個線程for (int i = 0; i < 10; ++i) {Worker* w = new Worker(i + 1);workers.append(w);w->start();}// 等待所有線程執行完成for (Worker* w : workers) {w->wait();delete w;}qDebug() << "所有任務執行完畢!";return 0;
}
程序輸出(示例)
線程1開始執行任務...
線程2開始執行任務...
線程3開始執行任務...
線程1任務完成!
線程4開始執行任務...
線程2任務完成!
線程5開始執行任務...
...
所有任務執行完畢!
可以看到:每次最多只有 3 個線程在執行任務,正是通過 QSemaphore
實現的并發控制。
五、代碼講解
-
QSemaphore semaphore(MAX_CONCURRENT);
初始化信號量對象,設定最大可用資源為 3,表示同時最多有 3 個線程能進入臨界區。 -
semaphore.acquire();
當前線程申請一個資源。如果當前資源不足(即已經有 3 個線程在運行),該線程會被阻塞。 -
semaphore.release();
當前線程完成任務后,釋放一個資源,讓其他等待中的線程可以繼續執行。
六、拓展建議
如果你希望進一步深入,可以嘗試以下拓展:
- 將
acquire()
替換為tryAcquire()
,實現非阻塞式資源申請邏輯 - 與
QThreadPool
和QRunnable
結合使用,構建線程池限流機制 - 配合 GUI,加入任務進度條,構建一個多任務調度界面
- 使用更復雜的資源數量控制(例如一次申請多個資源)
七、總結
QSemaphore
是多線程控制中非常實用的一種同步機制,它能有效地控制線程對資源的并發訪問數量。相比于 QMutex
的一對一互斥,QSemaphore
提供了更靈活的“多對多”資源控制能力。
在并發任務調度、限流、連接池管理等場景中,都是非常實用的解決方案。