GCD&&執行緒死鎖

weixin_33860722發表於2017-02-24

iOS GCD的摘要與批註:

1.GCD有兩個核心的概念:任務(執行什麼操作)和佇列(用來存放任務)。佇列分為併發佇列和序列佇列。其實除了這兩個比較核心的概念之外,還有一個很重要的概念就是“同步(sync)/非同步(async)”。!

1.1

同步和非同步主要影響:能不能開啟新的執行緒

同步:只是在當前執行緒中執行任務,不具備開啟新執行緒的能力
非同步:可以在新的執行緒中執行任務,具備開啟新執行緒的能力
併發和序列主要影響:任務的執行方式

併發:允許多個任務併發(同時)執行
序列:一個任務執行完畢後,再執行下一個任務

感覺同步的併發,即一個執行緒中同時併發地執行都任務感覺問題比較大,或許會有執行緒汙染吧。

1.2 併發佇列的任務處理順序,比如 ,1,2,3個任務。並行佇列又是怎麼在執行呢?

無論是同步還是非同步,併發佇列,雖然可以同時多個任務的處理,但是並行佇列的處理量,還是要根據當前系統狀態來。如果當前系統狀態最多處理2個任務,那麼1、2會排在前面,3什麼時候操作,就看1或者2誰先完成,然後3接在後面。而且在處理1和2的時候,可能會處理一會1,然後又去處理一會2,然後再回來處理1。

2.另外一個執行任務的方法:dispatch_barrier_async 柵欄。

場景:在前面的任務執行結束後它才執行,而且它後面的任務等它執行完成之後才會執行
注意:這個queue不能是全域性的併發佇列
dispatch_barrier_async(dispatch_queue_tqueue, dispatch_block_tblock);

感覺這個柵欄的用法,或許可以用於開子執行緒的時候,防止執行緒汙染吧!
或者非同步開啟序列佇列也能防止執行緒汙染吧。

3.全域性的併發佇列。
GCD預設已經提供了全域性的併發佇列,供整個應用使用,可以無需手動建立,使用dispatch_get_global_queue函式獲得全域性的併發佇列

// 獲得全域性併發佇列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

整個應用的全域性併發佇列看起來很多的樣子,其實一般都是這麼用

主佇列是放在主執行緒處理的。

5.序列與並行針對的是佇列,而同步與非同步,針對的則是執行緒。最大的區別在於,同步執行緒要阻塞當前執行緒,必須要等待同步執行緒中的任務執行完,返回以後,才能繼續執行下一任務;而非同步執行緒則是不用等待。

也就是說,子執行緒也有阻塞一說咯


五個案例讓你明白GCD死鎖

執行緒死鎖有“互等”,然後卡住的意思,
也由於和同/非同步處理順序,執行緒的等待導致佇列加入的順序與佇列的FIFO原則(先進先出)衝突引起。(挺拗口的,簡而言之,“順序”的鍋!)


1.其實斷點後,在左邊看到的哪些,主要是判斷當前斷點是否是在主執行緒,

2.跟UI相關的東西放到子執行緒去改,有可能會閃,(閃的原因真多),也有可能不會閃。但最好是放在主執行緒

-(void)fun1 {
    NSLog(@"1");
    
    if ([[NSThread currentThread] isMainThread]) {
        [UIView animateWithDuration:5 animations:^{
            self.view.backgroundColor = [UIColor blackColor];
        }];
        
        UIView *a = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
        a.backgroundColor= [UIColor redColor];
        
        [self.view addSubview:a];
        NSLog(@"2");

        
    } else {
         dispatch_async(dispatch_get_main_queue(), ^{
             [UIView animateWithDuration:5 animations:^{
                 self.view.backgroundColor = [UIColor blackColor];
             }];
             
             UIView *a = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
             a.backgroundColor= [UIColor redColor];
             
             [self.view addSubview:a];
             NSLog(@"2");
        
          });
    
    }
    

}

這樣寫能夠使得執行緒有順序

相關文章