iOS GCD中級篇 - dispatch_semaphore(訊號量)的理解及使用
阿新 • • 發佈:2018-12-04
理解這個概念之前,先丟擲一個問題
問題描述:
假設現在系統有兩個空閒資源可以被利用,但同一時間卻有三個執行緒要進行訪問,這種情況下,該如何處理呢?
或者
我們要下載很多圖片,併發非同步進行,每個下載都會開闢一個新執行緒,可是我們又擔心太多執行緒肯定cpu吃不消,那麼我們這裡也可以用訊號量控制一下最大開闢執行緒數。
定義:
1、訊號量:就是一種可用來控制訪問資源的數量的標識,設定了一個訊號量,線上程訪問之前,加上訊號量的處理,則可告知系統按照我們指定的訊號量數量來執行多個執行緒。
其實,這有點類似鎖機制了,只不過訊號量都是系統幫助我們處理了,我們只需要在執行執行緒之前,設定一個訊號量值,並且在使用時,加上訊號量處理方法就行了。
2、訊號量主要有3個函式,分別是:
//建立訊號量,引數:訊號量的初值,如果小於0則會返回NULL
dispatch_semaphore_create(訊號量值)
//等待降低訊號量
dispatch_semaphore_wait(訊號量,等待時間)
//提高訊號量
dispatch_semaphore_signal(訊號量)
注意,正常的使用順序是先降低然後再提高,這兩個函式通常成對使用。 (具體可參考下面的程式碼示例)
3、那麼就開頭提的問題,我們用程式碼來解決
-(void)dispatchSignal{ //crate的value表示,最多幾個資源可訪問 dispatch_semaphore_t semaphore = dispatch_semaphore_create(2); dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //任務1 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 1"); sleep(1); NSLog(@"complete task 1"); dispatch_semaphore_signal(semaphore); });<br> //任務2 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 2"); sleep(1); NSLog(@"complete task 2"); dispatch_semaphore_signal(semaphore); });<br> //任務3 dispatch_async(quene, ^{ dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); NSLog(@"run task 3"); sleep(1); NSLog(@"complete task 3"); dispatch_semaphore_signal(semaphore); }); }
執行結果:
總結:由於設定的訊號值為2,先執行兩個執行緒,等執行完一個,才會繼續執行下一個,保證同一時間執行的執行緒數不超過2。
這裡我們擴充套件一下,假設我們設定訊號值=1
dispatch_semaphore_create(1)<br><br>
結果:
如果設定訊號值=3
其實設定為3,就是不限制執行緒執行了,因為一共才只有3個執行緒。