dispatch_semaphore使用場景

一、定義

  • 1、信號量:就是一種可用來控制訪問資源的數(shù)量的標識,設(shè)定了一個信號量,在線程訪問之前,加上信號量的處理,則可告知系統(tǒng)按照我們指定的信號量數(shù)量來執(zhí)行多個線程。
    其實,這有點類似鎖機制了,只不過信號量都是系統(tǒng)幫助我們處理了,我們只需要在執(zhí)行線程之前,設(shè)定一個信號量值,并且在使用時,加上信號量處理方法就行了。

  • 2、簡單來講 信號量為0則阻塞線程,大于0則不會阻塞。則我們通過改變信號量的值,來控制是否阻塞線程,從而達到線程同步

  • 3、信號量主要有3個函數(shù),分別是:

      //創(chuàng)建信號量,參數(shù):信號量的初值,如果小于0則會返回NULL
      dispatch_semaphore_create(信號量值)
      //等待降低信號量
      dispatch_semaphore_wait(信號量,等待時間)
      //提高信號量
      dispatch_semaphore_signal(信號量)
    
  • 4、關(guān)于信號量,一般可以用停車來比喻

    停車場剩余4個車位,那么即使同時來了四輛車也能停的下。如果此時來了五輛車,那么就有一輛需要等待。信號量的值就相當于剩余車位的數(shù)目。dispatch_semaphore_wait函數(shù)就相當于來了一輛車,dispatch_semaphore_signal就相當于走了一輛車。停車位的剩余數(shù)目在初始化的時候就已經(jīng)指明了(dispatch_semaphore_create(long value)),調(diào)用一次dispatch_semaphore_signal,剩余的車位就增加一個;調(diào)用一次dispatch_semaphore_wait剩余車位就減少一個;當剩余車位為0時,再來車(即調(diào)用dispatch_semaphore_wait)就只能等待。有可能同時有幾輛車等待一個停車位。有些車主沒有耐心,給自己設(shè)定了一段等待時間,這段時間內(nèi)等不到停車位就走了,如果等到了就開進去停車。而有些車主就像把車停在這,所以就一直等下去。

二、使用場景1

假設(shè)現(xiàn)在系統(tǒng)有兩個空閑資源可以被利用,但同一時間卻有三個線程要進行訪問,這種情況下,該如何處理呢?

     //crate的value表示,最多幾個資源可訪問
    dispatch_semaphore_t samphore = dispatch_semaphore_create(2);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //dispatch_queue_t quene = dispatch_queue_create("com.anji.jiajia", DISPATCH_QUEUE_CONCURRENT);
    
    //任務(wù)1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"completed task 1");
        dispatch_semaphore_signal(samphore);
    });
    
    //任務(wù)2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"completed task 2");
        dispatch_semaphore_signal(samphore);
    });
    
    //任務(wù)3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"completed task 3");
        dispatch_semaphore_signal(samphore);
    });

運行結(jié)果:

2017-12-20 13:35:34.308282+0800 OCDemo[61949:15613320] run task 1
2017-12-20 13:35:34.308291+0800 OCDemo[61949:15613317] run task 2
2017-12-20 13:35:35.310784+0800 OCDemo[61949:15613320] completed task 1
2017-12-20 13:35:35.310784+0800 OCDemo[61949:15613317] completed task 2
2017-12-20 13:35:35.311016+0800 OCDemo[61949:15613319] run task 3
2017-12-20 13:35:36.313924+0800 OCDemo[61949:15613319] completed task 3

三、使用場景2

我們要下載很多圖片,并發(fā)異步進行,每個下載都會開辟一個新線程,可是我們又擔心太多線程肯定cpu吃不消,那么我們這里也可以用信號量控制一下最大開辟線程數(shù)。

 //crate的value表示,最多幾個資源可訪問
dispatch_semaphore_t samphore = dispatch_semaphore_create(5);
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < 15; i++) {
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task %d", i);
        [self downloadImge:^(BOOL isSuccess, NSString *errorMsg) {
            NSLog(@"BLock completed %d", i);
            dispatch_semaphore_signal(samphore);
        }];
    });
}

由于是異步執(zhí)行的,所以每次循環(huán)Block就會執(zhí)行dispatch_semaphore_wait,從而semaphore-1.當循環(huán)5次后semaphore==0,則會阻塞線程,直到執(zhí)行了Block的dispatch_semaphore_signal 才會繼續(xù)執(zhí)行。

四、使用場景3

在開發(fā)中我們需要處理下載多張照片等待所有網(wǎng)絡(luò)回調(diào)完之后才執(zhí)行后面的操作?;蛘叩却鄠€網(wǎng)絡(luò)請求,所有請求成功后數(shù)據(jù)融合處理。

 //crate的value表示,最多幾個資源可訪問
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

for (int i = 0; i < 5; i++) {
    dispatch_group_async(group, quene, ^{
        dispatch_semaphore_t samphore = dispatch_semaphore_create(0);
        [self downloadImge:^(BOOL isSuccess, NSString *errorMsg) {
            NSLog(@"task %d completed ", i);
            dispatch_semaphore_signal(samphore);
        }];
        dispatch_semaphore_wait(samphore, DISPATCH_TIME_FOREVER);
    });
}

dispatch_group_notify(group, quene, ^{
    NSLog(@"All task completed ====");
});

運行結(jié)果:

2017-12-20 14:22:03.162137+0800 OCDemo[64177:15790354] task 0 completed
2017-12-20 14:22:03.162138+0800 OCDemo[64177:15790351] task 3 completed
2017-12-20 14:22:04.165827+0800 OCDemo[64177:15790352] task 2 completed
2017-12-20 14:22:05.167003+0800 OCDemo[64177:15790368] task 4 completed
2017-12-20 14:22:05.166964+0800 OCDemo[64177:15790353] task 1 completed
2017-12-20 14:22:05.167153+0800 OCDemo[64177:15790368] All task completed ====

swift:DispatchSemaphore
GCD信號量

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容