1. 程式人生 > >Qt訊號量QSemaphore認識一下

Qt訊號量QSemaphore認識一下

  QSemaphore也是一個執行緒同步工具,這個工具像是QMutex的升級版。對於QMutex而言,只要一個執行緒拿到QMutex的使用權,其他執行緒再想要拿就必須等著。QSemaphore的使用權(或稱資源)數量可以是多個,假如設定了QSemaphore的使用權有10個,第一個執行緒請求了5個剩下5個,第二個執行緒可以再請求小於等於5個使用權。若第二個執行緒想要請求8個則會失敗,第二個執行緒只能繼續等待其他執行緒釋放資源。

    舉個公共廁所的例子,假如公共廁所有5個坑,QSemaphore是公共廁所的指示牌,指示牌上有五個指示燈。剛開始的時候燈是全滅的,表示坑都可用。這時候來了一個人,他看到有5個指示燈全是滅的,於是進去佔了一個坑,有一盞燈亮了。又過了一會兒來了一對基友,他們看到還有4個指示燈是滅的,於是進去佔了兩個坑,又有兩盞燈亮了。接著又來兩人佔滿了5個坑,5盞燈全亮了。這時候又來了一個人,看到5盞燈全亮了,沒辦法只能在門外等著,直到裡面有人出來,指示燈熄滅。

    寫個測試程式碼:

    1.定義一個公共資料bool陣列,它有5個元素,與之對應的QSemaphore也是5個元素。

blob.png

    2.定義公共資料的使用者Thread(繼承於QThread)。每個Thread都有一個成員變數mId在建構函式中賦值,以示區別。其run函式如下:

blob.png

run函式的功能是請求資源(gSemaphore.acquire()),若請求到資源則去gData中尋找可用的資料並列印,否則等待。當找到可用資料時睡眠3秒(模擬使用過程),最後將使用的資料設定為未使用並釋放資源(gSemaphore.qcquire())。

   3.建立100個Thread的物件並start,檢視執行結果:

blob.png

blob.png

程式每隔3秒輸出5個數據被佔用的資訊。說明請求到資源的執行緒可以使用,沒爭到的只能等待了。

題外話:

本例子其實還有個問題,那就是既然資源總數有5個,那麼這裡就會有5個執行緒同時去找gData中可用的資料。就好比5個人同時進入公共廁所後還得去搶坑。這裡可以在尋找gData前加一個QMutex,表示先來的先找,後來者等待,這樣可以確保佔坑的順序。所以說QSemaphore好像是QMutex的升級版,但兩者是可以配合使用的。