淺談GCD信號(hào)量dispatch_semaphore_t

理解信號(hào)量

理解信號(hào)量我們必須了解一下三個(gè)函數(shù):

  • dispatch_semaphore_create(long value);創(chuàng)建信號(hào)量,參數(shù)為設(shè)置信號(hào)量的初始值
  • dispatch_semaphore_signal(dispatch_semaphore_t dsema);發(fā)送當(dāng)前信號(hào)量,參數(shù)為當(dāng)前創(chuàng)建的信號(hào)量
  • dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);等待信號(hào)量,第一個(gè)為當(dāng)前等待的信號(hào)量,第二個(gè)參數(shù)為超時(shí)時(shí)間。當(dāng)?shù)却龝r(shí)間超過(guò)超時(shí)時(shí)間就不會(huì)繼續(xù)等待了。

信號(hào)量是一個(gè)整型值,在創(chuàng)建的時(shí)候會(huì)有一個(gè)初始值。當(dāng)執(zhí)行dispatch_semaphore_signal發(fā)送信號(hào)的時(shí)候信號(hào)量會(huì)加1,dispatch_semaphore_wait在信號(hào)量小于或等于0的時(shí)候會(huì)一直等待,直到超時(shí),并且會(huì)阻塞該線程,當(dāng)信號(hào)量大于0時(shí)會(huì)繼續(xù)執(zhí)行并對(duì)信號(hào)量執(zhí)行減1操作。

信號(hào)量使用

常見(jiàn)使用方法:

  1. 創(chuàng)建信號(hào)量
  2. 在要執(zhí)行的任務(wù)前設(shè)置信號(hào)量等待dispatch_semaphore_wait
  3. 當(dāng)其信號(hào)量的值大于0時(shí)則會(huì)執(zhí)行這個(gè)任務(wù),如小于等于0,則會(huì)一直等待阻塞當(dāng)前線程;
  4. 發(fā)送信號(hào)量dispatch_semaphore_signal

設(shè)置最大并發(fā)線程、多個(gè)異步任務(wù)執(zhí)行完再執(zhí)行下一步

    //創(chuàng)建線程組
    dispatch_group_t group = dispatch_group_create();   
    //創(chuàng)建值為10的信號(hào)量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
    //獲取全局并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
    for (int i = 0; i < 20; i++) {   
    //信號(hào)量小于等于0時(shí),線程等待
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
        dispatch_group_async(group, queue, ^{   
            NSLog(@"%i",i);   
            sleep(2);   
            //發(fā)送信號(hào)量 信號(hào)量值加1
            dispatch_semaphore_signal(semaphore);   
        });   
    }
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"do something");

從以上代碼可以看到,創(chuàng)建了一個(gè)線程組,并在線程組中引入了全局的并發(fā)隊(duì)列,同時(shí)創(chuàng)建了值為10的信號(hào)量,每次執(zhí)行dispatch_semaphore_wait后信號(hào)量的值會(huì)減1,并且加入一個(gè)異步任務(wù)到隊(duì)列中,直到信號(hào)量的值小于等于0時(shí)會(huì)阻塞當(dāng)前前線程,停止tian任務(wù),直到有任務(wù)完成信號(hào)量會(huì)加1。

多異步任務(wù)同步執(zhí)行

   dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(quene, ^{
        sleep(1);
        NSLog(@"task 1");
        dispatch_semaphore_signal(sem);
    });
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    
    dispatch_async(quene, ^{
        sleep(1);
        NSLog(@"task 2");
        dispatch_semaphore_signal(sem);
    });
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);

    
    dispatch_async(quene, ^{
        sleep(1);
        NSLog(@"task 3");
        dispatch_semaphore_signal(sem);
    });

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    //創(chuàng)建的4個(gè)任務(wù)執(zhí)行完之后
    NSLog(@"do something");

上面代碼我們創(chuàng)建了值為0的信號(hào)量,task1、task2、task3三個(gè)任務(wù)。當(dāng)信號(hào)量執(zhí)行到task1時(shí)只有task1執(zhí)行完,發(fā)送信號(hào)量dispatch_semaphore_signal后才會(huì)執(zhí)行task2。

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

相關(guān)閱讀更多精彩內(nèi)容

  • 一、dispatch_group 有時(shí)候我們會(huì)有這樣的需求:分別異步執(zhí)行兩個(gè)耗時(shí)任務(wù),當(dāng)兩個(gè)耗時(shí)任務(wù)都完成以后回到...
    司空123閱讀 1,615評(píng)論 0 3
  • 1.GCD信號(hào)量簡(jiǎn)介 GCD信號(hào)量機(jī)制主要涉及到以下三個(gè)函數(shù): dispatch_semaphore_create...
    VV木公子閱讀 41,365評(píng)論 18 230
  • 一、開端 隊(duì)列與任務(wù)創(chuàng)建 dispatch_queue_t 自定義GCD隊(duì)列,區(qū)分串行隊(duì)列與并行隊(duì)列 dispat...
    思想猿閱讀 507評(píng)論 0 0
  • 本文用來(lái)介紹 iOS 多線程中 GCD 的相關(guān)知識(shí)以及使用方法。這大概是史上最詳細(xì)、清晰的關(guān)于 GCD 的詳細(xì)講...
    花花世界的孤獨(dú)行者閱讀 575評(píng)論 0 1
  • 好久沒(méi)有好好寫點(diǎn)什么。 其實(shí)心里有一堆的苦惱,不知向誰(shuí)訴說(shuō)更不敢訴說(shuō)。每個(gè)人都有一堆的事,誰(shuí)還有心思理你的破事。自...
    找個(gè)安靜的角落閱讀 331評(píng)論 2 3

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