為了深刻理解死鎖和柵欄我寫了如下兩段程序澄耍,這兩段程序的結(jié)果分別如何勒
dispatch_queue_t queue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
dispatch_async(queue, ^{
NSLog(@"任務(wù)0");
});
dispatch_barrier_async(queue, ^{
NSLog(@"任務(wù)1");
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)2");
});
NSLog(@"任務(wù)3");
});
dispatch_async(queue, ^{
dispatch_barrier_sync(queue, ^{
NSLog(@"任務(wù)4");
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)5");
});
NSLog(@"任務(wù)6");
});
2018-03-05 19:01:29.962166+0800 Demo[80986:6088486] 任務(wù)3
2018-03-05 19:01:29.962375+0800 Demo[80986:6088486] 任務(wù)0
2018-03-05 19:01:29.962483+0800 Demo[80986:6088486] 任務(wù)1
2018-03-05 19:01:29.962720+0800 Demo[80986:6088486] 任務(wù)2
運(yùn)行起來可以看到第一段程序打印的是3 岂膳,0失暂,1, 2洲赵,第二段程序crash了鞋吉,為什么會產(chǎn)生這樣的結(jié)果勒
首先說下為什么會crash ,因?yàn)槲叶x的queue是串形隊(duì)列折欠,主要問題出在 dispatch_barrier_sync(queue, ^{ })會把block中的任務(wù)添加到queue的隊(duì)列的尾部贝或,而我外面包的 dispatch_async(queue, ^{ })block就是在這個queue中執(zhí)行的,所以block的內(nèi)容會在任務(wù)6執(zhí)行完了才會執(zhí)行锐秦,而sync又會把當(dāng)前隊(duì)列給堵塞住咪奖,所以crash了,跟這段代碼一樣 dispatch_sync(dispatch_get_main_queue(), ^{ });,主線程也是串形隊(duì)列酱床,所以crash羊赵。
那么第一段程序中為什么一定是3012,這是因?yàn)槲彝饷姘囊粚觔lock是queue中執(zhí)行扇谣,所以后面的block都會在任務(wù)3之后執(zhí)行昧捷,由于柵欄的作用,后面三個的順序一定是012罐寨,所以最后的結(jié)果就是3012.