dispatch_barrier_async、dispatch_apply、dispatch_block_notify、dispatch_group_notify

https://blog.csdn.net/Lu_Ca/article/details/80691965

1、dispatch_barrier_async

dispatch_barrier_async用于等待前面的任務(wù)執(zhí)行完畢后自己才執(zhí)行,而它后面的任務(wù)需等待它完成之后才執(zhí)行。一個典型的例子就是數(shù)據(jù)的讀寫,通常為了防止文件讀寫導(dǎo)致沖突,我們會創(chuàng)建一個串行的隊列,所有的文件操作都是通過這個隊列來執(zhí)行,比如FMDB,這樣就可以避免讀寫沖突。不過其實這樣效率是有提升的空間的,當(dāng)沒有更新數(shù)據(jù)時,讀操作其實是可以并行進行的,而寫操作需要串行的執(zhí)行,如何實現(xiàn)呢:

dispatch_queue_t queue = dispatch_queue_create("Database_Queue", DISPATCH_QUEUE_CONCURRENT);


? ? dispatch_async(queue, ^{

? ? ? ? NSLog(@"reading data1");

? ? });

? ? dispatch_async(queue, ^{

? ? ? ? NSLog(@"reading data2");

? ? });

? ? dispatch_barrier_async(queue, ^{

? ? ? ? NSLog(@"writing data1");

? ? ? ? [NSThread sleepForTimeInterval:1];


? ? });

? ? dispatch_async(queue, ^{

? ? ? ? [NSThread sleepForTimeInterval:1];

? ? ? ? NSLog(@"reading data3");

? ? });

執(zhí)行結(jié)果如下:

GCDTests[13360:584316] reading data2

GCDTests[13360:584317] reading data1

GCDTests[13360:584317] writing data1

GCDTests[13360:584317] reading data3

我們將寫數(shù)據(jù)的操作放在dispatch_barrier_async中,這樣能確保在寫數(shù)據(jù)的時候會等待前面的讀操作完成,而后續(xù)的讀操作也會等到寫操作完成后才能繼續(xù)執(zhí)行,提高文件讀寫的執(zhí)行效率。

2、dispatch_apply

dispatch_apply類似一個for循環(huán),會在指定的dispatch queue中運行block任務(wù)n次,如果隊列是并發(fā)隊列,則會并發(fā)執(zhí)行block任務(wù),dispatch_apply是一個同步調(diào)用,block任務(wù)執(zhí)行n次后才返回。

簡單的使用方法:

dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT);

//并發(fā)的運行一個block任務(wù)5次

dispatch_apply(5, queue, ^(size_t i) {

? ? NSLog(@"do a job %zu times",i+1);

});

NSLog(@"go on");

輸出結(jié)果:

GCDTests[10029:760640] do a job 2 times

GCDTests[10029:760640] do a job 1 times

GCDTests[10029:760640] do a job 3 times

GCDTests[10029:760640] do a job 5 times

GCDTests[10029:760640] do a job 4 times

GCDTests[10029:760640] go on

3、dispatch_block_notify

dispatch_block_notify當(dāng)觀察的某個block執(zhí)行結(jié)束之后立刻通知提交另一特定的block到指定的queue中執(zhí)行,該函數(shù)有三個參數(shù),第一參數(shù)是需要觀察的block,第二個參數(shù)是被通知block提交執(zhí)行的queue,第三參數(shù)是當(dāng)需要被通知執(zhí)行的block,函數(shù)的原型:

void dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue,

? ? ? ? dispatch_block_t notification_block);

具體使用的方法:

? ? dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);

? ? dispatch_block_t previousBlock = dispatch_block_create(0, ^{

? ? ? ? NSLog(@"previousBlock begin");

? ? ? ? [NSThread sleepForTimeInterval:1];

? ? ? ? NSLog(@"previousBlock done");

? ? });

? ? dispatch_async(queue, previousBlock);

? ? dispatch_block_t notifyBlock = dispatch_block_create(0, ^{

? ? ? ? NSLog(@"notifyBlock");

? ? });

? ? //當(dāng)previousBlock執(zhí)行完畢后,提交notifyBlock到global queue中執(zhí)行

? ? dispatch_block_notify(previousBlock, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), notifyBlock);

運行結(jié)果:

GCDTests[17129:895673] previousBlock begin

GCDTests[17129:895673] previousBlock done

GCDTests[17129:895673] notifyBlock

4、dispatch_group_wait

dispatch_group_wait會同步地等待group中所有的block執(zhí)行完畢后才繼續(xù)執(zhí)行,類似于dispatch barrier

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_t group = dispatch_group_create();

//將任務(wù)異步地添加到group中去執(zhí)行

dispatch_group_async(group,queue,^{ NSLog(@"block1"); });

dispatch_group_async(group,queue,^{ NSLog(@"block2"); });

dispatch_group_wait(group,DISPATCH_TIME_FOREVER);

NSLog(@"go on");

執(zhí)行結(jié)果如下,只有block1跟block2執(zhí)行完畢后才會執(zhí)行dispatch_group_wait后面的內(nèi)容。

GCDTests[954:41031] block2

GCDTests[954:41032] block1

GCDTests[954:40847] go on

5、dispatch_group_notify

功能與dispatch_group_wait類似,不過該過程是異步的,不會阻塞該線程,dispatch_group_notify有三個參數(shù)

void dispatch_group_notify(dispatch_group_t group, //要觀察的group

? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_queue_t queue,? //block執(zhí)行的隊列

? ? ? ? ? ? ? ? ? ? ? ? ? dispatch_block_t block);? //當(dāng)group中所有任務(wù)執(zhí)行完畢之后要執(zhí)行的block

簡單的示意用法:

dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,queue,^{ NSLog(@"block1"); });

dispatch_group_async(group,queue,^{ NSLog(@"block2"); });

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

? ? NSLog(@"done");

});

NSLog(@"go on");

可以看到如下的執(zhí)行結(jié)果

GCDTests[1046:45104] go on

GCDTests[1046:45153] block1

GCDTests[1046:45152] block2

GCDTests[1046:45104] done

?著作權(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ù)。

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

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