- 同步主隊(duì)列執(zhí)行任務(wù)。
主線程有一個(gè)特點(diǎn):主線程會(huì)先執(zhí)行主線程上的代碼片段,然后才會(huì)去執(zhí)行放在主隊(duì)列中的任務(wù)。
同步執(zhí)行 dispatch_sync函數(shù)的特點(diǎn):該函數(shù)只有在該函數(shù)中被添加到某隊(duì)列的某方法執(zhí)行完畢之后才會(huì)返回。即 方法會(huì)等待 task 執(zhí)行完再返回
dispatch_sync 函數(shù)本身是放在主線程中執(zhí)行的,也就是說(shuō)他本身也是屬于主線程執(zhí)行任務(wù)的一部分。根據(jù)主線程的特點(diǎn):主線程會(huì)等主線程上的代碼執(zhí)行完畢之后才會(huì)去執(zhí)行放置到主隊(duì)列中的 task;再根據(jù) disptach_sync 函數(shù)特點(diǎn), task 不執(zhí)行完畢,dispatch_sync 函數(shù)不返回。這樣,dispatch_sync 為了返回會(huì)等 task 執(zhí)行完畢也就是主線程執(zhí)行完,而 task 執(zhí)行又等著主線程上的代碼執(zhí)行完,也即主線程上 dispatch_sync 代碼執(zhí)行完。
-
主隊(duì)列和主線程相互等待會(huì)造成死鎖
dispatch_sync(dispatch_get_main_queue(), ^(void){
NSLog(@"這里死鎖了");
});
NSLog(@"下面的不執(zhí)行了");
解決方案:
dispatch_async(dispatch_get_main_queue(), ^(void){
NSLog(@"這里死鎖了"); // 現(xiàn)在沒(méi)有死鎖
});
dispatch_sync(dispatch_get_global_queue(0, 0), ^(void){
NSLog(@"這里死鎖了"); // 現(xiàn)在沒(méi)有死鎖
});
- 異步中包含同步,并且用的都是串行隊(duì)列
異步串行隊(duì)列中遇到同步串行。同步執(zhí)行阻塞線程,需要等待block 執(zhí)行完往下執(zhí)行,下面又先添加到串行隊(duì)列,需要執(zhí)行完才能執(zhí)行同步任務(wù)。解決方案, 1. 異步和同步使用不同的隊(duì)列。2. 全部使用并行隊(duì)列。
dispatch_queue_t queue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);
NSLog(@"1");//任務(wù)1
dispatch_async(queue,^{
NSLog(@"2");//任務(wù)2
dispatch_sync(queue,^{
NSLog(@"3");//任務(wù)3
});
NSLog(@"4");//任務(wù)4
});
NSLog(@"5");//任務(wù)5
// 1
// 5
// 2
解決方案:
dispatch_queue_t queue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);
NSLog(@"1");//任務(wù)1
dispatch_async(queue,^{
NSLog(@"2");//任務(wù)2
dispatch_sync(dispatch_get_main_queue(),^{
NSLog(@"3");//任務(wù)3
});
NSLog(@"4");//任務(wù)4
});
NSLog(@"5");//任務(wù)5
// 1
// 5
// 2
// 3
// 4
dispatch_queue_t queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");//任務(wù)1
dispatch_async(queue,^{
NSLog(@"2");//任務(wù)2
dispatch_sync(queue,^{
NSLog(@"3");//任務(wù)3
});
NSLog(@"4");//任務(wù)4
});
NSLog(@"5");//任務(wù)5
// 1
// 5
// 2
// 3
// 4
-
阻塞主隊(duì)列,同步主隊(duì)列任務(wù)死鎖。
dispatch_async(dispatch_get_global_queue(0,0),^{NSLog(@"1");//任務(wù)1
dispatch_sync(dispatch_get_main_queue(),^{
NSLog(@"2");//任務(wù)2
});
NSLog(@"3");//任務(wù)3
});
NSLog(@"4");//任務(wù)4
while(1){
}
NSLog(@"5");//任務(wù)5
// 4
// 1
總結(jié):
造成死鎖的原因是:
在同一個(gè)串行的隊(duì)列中,同步添加block。