iOS GCD (一) 任務+隊列 基礎組合
iOS GCD (二 ) dispatch_group 隊列組
iOS GCD(三) dispatch_barrier_async 柵欄方法
iOS GCD (四) dispatch_semaphore 信號量
iOS GCD(五) 死鎖案例分析
iOS GCD(六)線程加鎖
死鎖一:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1========%@",[NSThread currentThread]);
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2========%@",[NSThread currentThread]);
});
NSLog(@"3========%@",[NSThread currentThread]);
}
2018-04-25 22:39:46.674860+0700 GCDCC[39201:2495255] 1========<NSThread: 0x604000071d00>{number = 1, name = main}
(lldb)
分析:
我們先做一個定義:- (void)viewDidLoad{} ---> 任務A,GCD同步函數(shù) --->任務B。
總而言之呢,大概是這樣的,首先,任務A在主隊列,并且已經(jīng)開始執(zhí)行,在主線程打印出1===... ...,然后這時任務B被加入到主隊列中,并且同步執(zhí)行,這尼瑪事都大了,系統(tǒng)說,同步執(zhí)行啊,那我不開新的線程了,任務B說我要等我里面的Block函數(shù)執(zhí)行完成,要不我就不返回,但是主隊列說了,玩蛋去,我是串行的,你得等A執(zhí)行完才能輪到你,不能壞了規(guī)矩,同時,任務B作為任務A的內部函數(shù),必須等任務B執(zhí)行完函數(shù)返回才能執(zhí)行下一個任務。那就造成了,任務A等待任務B完成才能繼續(xù)執(zhí)行,但作為串行隊列的主隊列又不能讓任務B在任務A未完成之前開始執(zhí)行,所以任務A等著任務B完成,任務B等著任務A完成,等待,永久的等待。所以就死鎖了。簡單不?下面我們慎重看一下我們無意識書寫的代碼!
死鎖二:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_queue_t q = dispatch_queue_create("chuan", DISPATCH_QUEUE_SERIAL);
dispatch_sync(q, ^{
NSLog(@"1========%@",[NSThread currentThread]);
dispatch_sync(q, ^{
NSLog(@"2========%@",[NSThread currentThread]);
});
dispatch_async(q, ^{
NSLog(@"3========%@",[NSThread currentThread]);
});
});
}
2018-04-26 09:57:42.324541+0700 GCD[75126:3811592] 1========<NSThread: 0x600000073580>{number = 1, name = main}
(lldb)
分析:
首先隊列是一個串行隊列,串行隊列的特點,一個任務執(zhí)行完畢執(zhí)行下一個任務,開不線程取決于任務是同步還是異步,開幾條線程決定于世串行還是并行,此時的情況說明 任務1,任務2,任務3全部都在同一條線程上執(zhí)行,并且線程是同步執(zhí)行的,講到這里我想你已經(jīng)懂了,比如說任務A正在執(zhí)行任務,遇到了任務B,任務A我必須要執(zhí)行完我的任務任務B你讓開道,任務B是個死腦筋,會說我們兩個在同一條道上,我的原則和你的原則一樣,你不執(zhí)行完,休想讓我執(zhí)行,這個時候任務A和任務B就開始了漫長的相互等待導致最后的崩潰。
這個和案例一一樣只是可以再一次深入理解一下
死鎖三
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_queue_t q = dispatch_queue_create("chuan", DISPATCH_QUEUE_SERIAL);
dispatch_async(q, ^{
NSLog(@"1========%@",[NSThread currentThread]);
dispatch_sync(q, ^{
NSLog(@"2========%@",[NSThread currentThread]);
});
dispatch_async(q, ^{
NSLog(@"3========%@",[NSThread currentThread]);
});
});
}
2018-04-26 10:14:19.802281+0700 GCD[75370:3825211] 1========<NSThread: 0x604000274b80>{number = 3, name = (null)}
(lldb)
分析:
這個案例和案例一,案例二一樣,屬于同一個案例,只是不同的形式,看到這里是不是有種666的感覺~
首先 我們還是從隊列開始分析,這是一個串行隊列,串行隊列的特點是一個任務執(zhí)行完執(zhí)行下一個任務,道理同案例一案例二,不解釋了 兄弟們,希望幫到你們~