-
GCD中有兩個(gè)用來(lái)執(zhí)行任務(wù)的常用函數(shù)
用同步方法執(zhí)行任務(wù),其中 queue 是隊(duì)列,block 是任務(wù)
dispatch_sync(dispatch_queue_t queue, dispatch_block_t blcok);用異步方法執(zhí)行任務(wù),其中 queue 是隊(duì)列,block 是任務(wù)
dispatch_async(dispatch_queue_t queue, dispatch_block_t blcok);
同步和異步的區(qū)別
同步:只能在當(dāng)前線程中執(zhí)行任務(wù),不具備開(kāi)啟新線程的能力
異步:可以在新線程中執(zhí)行任務(wù),具備開(kāi)啟新線程的能力。-
GCD中還有兩個(gè)用來(lái)執(zhí)行任務(wù)的函數(shù)
當(dāng)我們的任務(wù)有依賴關(guān)系的時(shí)候,比如任務(wù)1和2執(zhí)行完畢后才能執(zhí)行任務(wù)3和4,這時(shí)候我們可以用到這個(gè)函數(shù)——柵欄函數(shù)。其中 queue 是隊(duì)列,block 是任務(wù)。提交一個(gè)柵欄函數(shù)在執(zhí)行中,它會(huì)等待柵欄函數(shù)執(zhí)行完再去執(zhí)行下一行代碼(注意是下一行代碼),同步柵欄函數(shù)是在主線程中執(zhí)行的
dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t blcok);提交一個(gè)柵欄函數(shù)在異步執(zhí)行中,它會(huì)立馬返回開(kāi)始執(zhí)行下一行代碼(不用等待任務(wù)執(zhí)行完畢)
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t blcok);
共同點(diǎn)
1、都會(huì)等待在它前面插入隊(duì)列的任務(wù)(1、2、3)先執(zhí)行完
2、都會(huì)等待他們自己的任務(wù)(barrier)執(zhí)行完再執(zhí)行后面的任務(wù)(4、5、6)(注意這里說(shuō)的是任務(wù)不是下一行代碼)
不同點(diǎn)
1、dispatch_barrier_sync需要等待自己的任務(wù)(barrier)結(jié)束之后,才會(huì)繼續(xù)添加并執(zhí)行寫(xiě)在barrier后面的任務(wù)(4、5、6),然后執(zhí)行后面的任務(wù)
2、dispatch_barrier_async將自己的任務(wù)(barrier)插入到queue之后,不會(huì)等待自己的任務(wù)結(jié)束,它會(huì)繼續(xù)把后面的任務(wù)(4、5、6)插入到queue,然后執(zhí)行任務(wù)。
//并發(fā)隊(duì)列 柵欄函數(shù)
- (void)concurrentQueueAsyncAndSync2BarrrierTest
{
dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"任務(wù)0 %d",i);
}];
});
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"任務(wù)1 %d",i);
}];
});
NSLog(@"同步柵欄 start??");
dispatch_barrier_sync(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"同步柵欄, %@",[NSThread currentThread]);
}];
});
NSLog(@"同步柵欄 end??");
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"任務(wù)2 %d",i);
}];
});
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"任務(wù)3 %d",i);
}];
});
NSLog(@"異步柵欄 start ??");
dispatch_barrier_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"異步柵欄 %@",[NSThread currentThread]);
}];
});
NSLog(@"異步柵欄 end ??");
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"任務(wù)4 %d",i);
}];
});
dispatch_async(concurrentQueue, ^{
[self forNumIncrementCondition:5 actionBlock:^(int i) {
NSLog(@"任務(wù)5 %d",i);
}];
});
}
- (void)forNumIncrementCondition:(NSUInteger )num actionBlock:(void(^)(int i))actionBlcok
{
for (int a = 0; a < num; a ++)
{
if (actionBlcok) {
actionBlcok(a);
}
}
}
答應(yīng)結(jié)果如下
PPFGCD_demo1[5141:1319243] 同步柵欄 start??
PPFGCD_demo1[5141:1319371] 任務(wù)0 0
PPFGCD_demo1[5141:1322592] 任務(wù)1 0
PPFGCD_demo1[5141:1319371] 任務(wù)0 1
PPFGCD_demo1[5141:1322592] 任務(wù)1 1
PPFGCD_demo1[5141:1319371] 任務(wù)0 2
PPFGCD_demo1[5141:1322592] 任務(wù)1 2
PPFGCD_demo1[5141:1319371] 任務(wù)0 3
PPFGCD_demo1[5141:1322592] 任務(wù)1 3
PPFGCD_demo1[5141:1319371] 任務(wù)0 4
PPFGCD_demo1[5141:1322592] 任務(wù)1 4
PPFGCD_demo1[5141:1319243] 同步柵欄, <NSThread: 0x60800006f300>{number = 1, name = main}
PPFGCD_demo1[5141:1319243] 同步柵欄, <NSThread: 0x60800006f300>{number = 1, name = main}
PPFGCD_demo1[5141:1319243] 同步柵欄, <NSThread: 0x60800006f300>{number = 1, name = main}
PPFGCD_demo1[5141:1319243] 同步柵欄, <NSThread: 0x60800006f300>{number = 1, name = main}
PPFGCD_demo1[5141:1319243] 同步柵欄, <NSThread: 0x60800006f300>{number = 1, name = main}
PPFGCD_demo1[5141:1319243] 同步柵欄 end??
PPFGCD_demo1[5141:1319243] 異步柵欄 start ??
PPFGCD_demo1[5141:1319371] 任務(wù)3 0
PPFGCD_demo1[5141:1322592] 任務(wù)2 0
PPFGCD_demo1[5141:1319243] 異步柵欄 end ??
PPFGCD_demo1[5141:1319371] 任務(wù)3 1
PPFGCD_demo1[5141:1322592] 任務(wù)2 1
PPFGCD_demo1[5141:1319371] 任務(wù)3 2
PPFGCD_demo1[5141:1322592] 任務(wù)2 2
PPFGCD_demo1[5141:1319371] 任務(wù)3 3
PPFGCD_demo1[5141:1322592] 任務(wù)2 3
PPFGCD_demo1[5141:1319371] 任務(wù)3 4
PPFGCD_demo1[5141:1322592] 任務(wù)2 4
PPFGCD_demo1[5141:1322592] 異步柵欄 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
PPFGCD_demo1[5141:1322592] 異步柵欄 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
PPFGCD_demo1[5141:1322592] 異步柵欄 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
PPFGCD_demo1[5141:1322592] 異步柵欄 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
PPFGCD_demo1[5141:1322592] 異步柵欄 <NSThread: 0x60c00046dbc0>{number = 5, name = (null)}
PPFGCD_demo1[5141:1322592] 任務(wù)4 0
PPFGCD_demo1[5141:1319371] 任務(wù)5 0
PPFGCD_demo1[5141:1322592] 任務(wù)4 1
PPFGCD_demo1[5141:1319371] 任務(wù)5 1
PPFGCD_demo1[5141:1322592] 任務(wù)4 2
PPFGCD_demo1[5141:1319371] 任務(wù)5 2
PPFGCD_demo1[5141:1322592] 任務(wù)4 3
PPFGCD_demo1[5141:1319371] 任務(wù)5 3
PPFGCD_demo1[5141:1322592] 任務(wù)4 4
PPFGCD_demo1[5141:1319371] 任務(wù)5 4
情景分析:
同步柵欄添加進(jìn)入隊(duì)列的時(shí)候,當(dāng)前線程會(huì)被鎖死,直到同步柵欄之前的任務(wù)和同步柵欄任務(wù)本身執(zhí)行完畢時(shí),當(dāng)前線程才會(huì)打開(kāi)然后繼續(xù)執(zhí)行下一句代碼。
注意:
在使用柵欄函數(shù)時(shí).使用自定義隊(duì)列才有意義,如果用的是串行隊(duì)列或者系統(tǒng)提供的全局并發(fā)隊(duì)列,這個(gè)柵欄函數(shù)的作用等同于一個(gè)同步函數(shù)的作用