1. 程式人生 > >iOS GCD中級篇 - dispatch_semaphore(訊號量)的理解及使用

iOS GCD中級篇 - dispatch_semaphore(訊號量)的理解及使用

理解這個概念之前,先丟擲一個問題

問題描述:

假設現在系統有兩個空閒資源可以被利用,但同一時間卻有三個執行緒要進行訪問,這種情況下,該如何處理呢?

或者

我們要下載很多圖片,併發非同步進行,每個下載都會開闢一個新執行緒,可是我們又擔心太多執行緒肯定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個執行緒。

轉自:http://www.cnblogs.com/yajunLi/p/6274282.html