iOS GCD 的理解 (一)

來源:互聯網
上載者:User

標籤:

  • 基本概念

  瞭解多線程之前,首先我們要對作業系統關於多線程方面的名詞解釋一下,學過作業系統課程的同學可以跳過。

  1. 進程: 一個具有一定獨立功能的程式關於某個資料集合的一次運行活動。可以理解成一個運行中的APP。
  2. 線程:程式能夠進行運算調度的最小單元,一個進程可以包含多個線程。
  3. 同步:只能在當前線程按先後順序依次執行,不開啟新線程,在完成了它預定的任務後才返回。
  4. 非同步:可以在當前線程開啟多個新線程執行,執行的順序無法保證,會立即返回,預定的任務會完成但不會等它完成。因此,一個非同步函數不會阻塞當前線程去執行下一個函數。
  5. 並行:對於多核CPU來說,可以在同一時間執行多個任務。對於單核的CPU來說,是在很短的時間片段輪詢執行,讓人感覺是同時執行。
  6. 串列:線程執行只能依次逐一先後有序的執行。
  7. 隊列:GCD 提供有 dispatch queues 來處理代碼塊,這些隊列管理你提供給 GCD 的任務並用 FIFO 順序執行這些任務。這就保證了第一個被添加到隊列裡的任務會是隊列中第一個開始的任務,而第二個被添加的任務將第二個開始,如此直到隊列的終點。隊列分為串列隊列和並行隊列,串列隊列(Serial Queus)串列隊列中的任務一次執行一個,每個任務只在前一個任務完成時才開始。而且,你不知道在一個 Block 結束和下一個開始之間的時間長度。並發隊列(Concurrent Queus):在並發隊列中的任務能得到的保證是它們會按照被添加的順序開始執行,任務可能以任意順序完成,你不會知道何時開始運行下一個任務,或者任意時刻有多少 Block 在運行。
  • 隊列和任務的特點

  隊列以先進先出的方式進行任務的調度,當輪到某個任務執行的時候,從隊列取出,交給一個線程去執行。

  1. 串列隊列:任務按照添加的順序被調度,當前任務不執行完畢,不會進行下次任務的調度。
  2. 並行隊列:只要有閒置線程,隊列就會調度當前任務,交給線程去執行,不需要考慮前面是都有任務在執行,只要有線程可以利用,隊列就會調度任務。
  3. main隊列:是一個串列隊列,主要用於UI更新相關的任務。
  4. global隊列:全域隊列是一個並行隊列。
  5. 同步任務:不會開新線程,任務一個接著一個執行。
  6. 非同步任務:會新開線程,任務可以並發執行。
  • 任務和隊列組合
  1. 串列隊列同步任務:組合特點串列隊列順序執行,同步任務不會開新線程,所以是one-by-one。
dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.demo", DISPATCH_QUEUE_SERIAL);        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:3];        NSLog(@"任務1");    });        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:1];        NSLog(@"任務2");    });        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:2];        NSLog(@"任務3");    });        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:1];        NSLog(@"任務4");    });

  列印如下:

  2016-08-04 15:42:53.334 GCDTestDemo[6858:1582521] 任務1

  2016-08-04 15:42:54.342 GCDTestDemo[6858:1582521] 任務2

  2016-08-04 15:42:56.348 GCDTestDemo[6858:1582521] 任務3

  2016-08-04 15:42:57.353 GCDTestDemo[6858:1582521] 任務4

  2.串列隊列非同步任務:串列隊列當前任務沒有結束,不會進行下次調度。非同步任務會在另一個線程上one-by-one的執行。

  執行結果如下

  

   3.並行隊列同步任務:並行隊列不用等待當前任務,只要有線程,就會調度下一個任務,同步任務不會開啟新的線程,所以組合後還是one-by-one的執行。

  

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        [self testSerialQueue];        NSLog(@"%@",[NSThread currentThread]);    });

 

dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.demo", DISPATCH_QUEUE_CONCURRENT);        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:3];        NSLog(@"任務1 %@",[NSThread currentThread]);    });        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:1];        NSLog(@"任務2 %@",[NSThread currentThread]);    });        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:2];        NSLog(@"任務3 %@",[NSThread currentThread]);    });        dispatch_sync(serialQueue, ^{        [NSThread sleepForTimeInterval:3];        NSLog(@"任務4 %@",[NSThread currentThread]);    });

  執行結果:

2016-08-04 18:03:52.823 GCDTestDemo[7064:1618448] 任務1 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:53.827 GCDTestDemo[7064:1618448] 任務2 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:55.832 GCDTestDemo[7064:1618448] 任務3 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:58.838 GCDTestDemo[7064:1618448] 任務4 <NSThread: 0x14d47590>{number = 3, name = (null)}

2016-08-04 18:03:58.838 GCDTestDemo[7064:1618448] <NSThread: 0x14d47590>{number = 3, name = (null)}

  4.並行隊列非同步任務:再上一條中說明了並行隊列的特點,而非同步執行是任務可以開啟新的線程,所以這中組合可以實現任務的並發,再實際開發中也是經常會用到的。

  

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        [self testSerialQueue];        NSLog(@"%@",[NSThread currentThread]);    });

 

- (void)testSerialQueue{    dispatch_queue_t serialQueue = dispatch_queue_create("com.gcd.demo", DISPATCH_QUEUE_CONCURRENT);        dispatch_async(serialQueue, ^{        [NSThread sleepForTimeInterval:3];        NSLog(@"任務1 %@",[NSThread currentThread]);    });        dispatch_async(serialQueue, ^{        [NSThread sleepForTimeInterval:1];        NSLog(@"任務2 %@",[NSThread currentThread]);    });        dispatch_async(serialQueue, ^{        [NSThread sleepForTimeInterval:2];        NSLog(@"任務3 %@",[NSThread currentThread]);    });        dispatch_async(serialQueue, ^{        [NSThread sleepForTimeInterval:3];        NSLog(@"任務4 %@",[NSThread currentThread]);    });}

   執行結果:

2016-08-04 18:07:39.746 GCDTestDemo[7069:1619191] <NSThread: 0x15e56cf0>{number = 2, name = (null)}

2016-08-04 18:07:40.752 GCDTestDemo[7069:1619197] 任務2 <NSThread: 0x15d7dd00>{number = 3, name = (null)}

2016-08-04 18:07:41.752 GCDTestDemo[7069:1619196] 任務3 <NSThread: 0x15d514f0>{number = 4, name = (null)}

2016-08-04 18:07:42.751 GCDTestDemo[7069:1619198] 任務1 <NSThread: 0x15d79b90>{number = 5, name = (null)}

2016-08-04 18:07:42.752 GCDTestDemo[7069:1619199] 任務4 <NSThread: 0x15d644e0>{number = 6, name = (null)}

    

                   

 

iOS GCD 的理解 (一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.