使用 GCD 控制線程執(zhí)行順序

前言

需求:有三個(gè)異步執(zhí)行的任務(wù)A、B、C,任務(wù) C 必須等待任務(wù) A任務(wù) B 執(zhí)行完畢才執(zhí)行。

本文分別采用三種方法來實(shí)現(xiàn)線程執(zhí)行順序的控制,semaphore、barrier、group。詳細(xì)代碼可以參考 WZHWaitThread

Semaphore

執(zhí)行 dispatch_semaphore_wait 時(shí),如果信號(hào)量大于 0,可以繼續(xù)執(zhí)行并把信號(hào)量減一;如果信號(hào)量小于等于 0,線程被阻塞,等待信號(hào)量大于 0。dispatch_semaphore_signal 釋放信號(hào)量,使信號(hào)量加一。dispatch_semaphore_waitdispatch_semaphore_signal 配合使用可以控制線程的執(zhí)行。

- (void)waitThreadWithSemaphore {
    dispatch_queue_t currentQueue = dispatch_queue_create("current queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    
    dispatch_async(currentQueue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"Thread A %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_async(currentQueue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"Thread B %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_async(currentQueue, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"Thread C %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
        dispatch_semaphore_signal(semaphore);
        // dispatch_semaphore_wait 和 dispatch_semaphore_signal 必須成對(duì)使用
    });
    
    NSLog(@"Wait Thread Test.");
}

Barrier

dispatch_barrier_async 可以攔截線程的執(zhí)行,在 dispatch_barrier_async 之前的線程執(zhí)行完才會(huì)執(zhí)行 dispatch_barrier_async 之后的的線程。這里注意兩點(diǎn):

  1. 在使用柵欄函數(shù)時(shí),使用自定義的并行隊(duì)列才有意義,如果用的是串行隊(duì)列或者系統(tǒng)提供的全局并發(fā)隊(duì)列,這個(gè)柵欄函數(shù)的作用等同于一個(gè) dispatch_sync 的作用。

The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like the dispatch_sync function.

  1. dispatch_barrier_asyncdispatch_barrier_sync 的區(qū)別

dispatch_barrier_sync 需要等待自己的任務(wù)結(jié)束之后才會(huì)繼續(xù)程序,然后執(zhí)行后面的任務(wù);
dispatch_barrier_async 將自己的任務(wù)插入到 queue 之后,不會(huì)等待自己的任務(wù)結(jié)束,會(huì)繼續(xù)把后面的任務(wù)插入到 queue。

- (void)waitThreadWithBarrier {
    dispatch_queue_t queue = dispatch_queue_create("current queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"Thread A %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"Thread B %@", [NSThread currentThread]);
    });
    
    dispatch_barrier_sync(queue, ^{
        NSLog(@"barrier %@", [NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"Thread C %@", [NSThread currentThread]);
    });
    
    NSLog(@"Wait Thread Test In %@", [NSThread currentThread]);
}

Group

dispatch_group 可以把相關(guān)的任務(wù)歸并到一個(gè)組內(nèi)來執(zhí)行,通過監(jiān)聽組內(nèi)所有任務(wù)的執(zhí)行情況來做相應(yīng)處理。待任務(wù)組執(zhí)行完畢時(shí)調(diào)用 dispatch_group_notify,不會(huì)阻塞當(dāng)前線程。或者 dispatch_group_wait 可以等待組任務(wù)完成,會(huì)阻塞當(dāng)前線程,當(dāng)任務(wù)組執(zhí)行完畢時(shí),才會(huì)解除阻塞當(dāng)前線程。

注意:不要在主線程使用 dispatch_group_wait,如果 group 中如果添加主隊(duì)列后再使用 dispatch_group_wait 有可能引起死鎖。

- (void)waitThreadWithGroup {
    dispatch_queue_t queue = dispatch_queue_create("current queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"Thread A %@", [NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"Thread B %@", [NSThread currentThread]);
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"Thread C %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        NSLog(@"Wait Thread Test In %@", [NSThread currentThread]);
    });
}
?著作權(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)容

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