GCD總結(一)


 
 GCD為我們提供了三種類型的調度隊列(dispatch queue),分別為串行,並行和主調度隊列。

    串行(Serial)

    你可以創建任意個數的串行隊列,每個隊列依次執行添加的任務,一個隊列同一時刻只能執行一個任務(串行),但是各個隊列之間不影響,可以並發執行。每個隊列中的任務運行在一個由各自串行隊列維護的獨立線程上,一個隊列中只有一個線程。
  下面,我將創建一個串行隊列,添加兩個任務,來演示串行執行的過程。
  
 1 UInt32 loopCount = 1000;
 2     
 3     void (^taskFirst)(void) = ^{
 4         NSLog(@"taskFirst 任務開始執行\r\n");
 5         
 6         for (UInt32 i = 0; i < loopCount; i++) {
 7             
 8         }
 9         NSLog(@"taskFirst 任務結束\r\n");
10     };
11     
12     void (^taskSecond)(void) = ^{
13         NSLog(@"taskSecond任務開始執行\r\n");
14         for (UInt32 i = 0; i < loopCount; i ++) {
15             
16         }
17         NSLog(@"taskSecond 任務結束\r\n");
18     };
19     dispatch_queue_t serialQueue;
20     serialQueue = dispatch_queue_create("serialDemo", NULL);
21     dispatch_async(serialQueue, taskFirst);
22     NSLog(@"taskfirst 已經加入隊列\r\n");
23     dispatch_async(serialQueue, taskSecond);
24     NSLog(@"tasksecond 已經加入隊列\r\n");

運行得到結果1:

2012-05-14 18:45:01.766 GDCDemo[389:f803] taskfirst 已經加入隊列

2012-05-14 18:45:01.766 GDCDemo[389:11103] taskFirst 任務開始執行

2012-05-14 18:45:01.767 GDCDemo[389:f803] tasksecond 已經加入隊列

2012-05-14 18:45:01.768 GDCDemo[389:11103] taskFirst 任務結束

2012-05-14 18:45:01.768 GDCDemo[389:11103] taskSecond任務開始執行

2012-05-14 18:45:01.772 GDCDemo[389:11103] taskSecond 任務結束

運行結果跟我們的預計一樣,taskFirst執行完之后,才執行taskSecond。而且,通過“xxx任務加入隊列”的提示,任務運行的線程跟主線程不是同一個。

下面,我們繼續對代碼做點調整,讓它演示不同隊列之間的任務並行運行。

 1 UInt32 loopCount = 1000;
 2     UInt32 loopCountFirst = 10000000;
 3     
 4     void (^taskFirst)(void) = ^{
 5         NSLog(@"taskFirst 任務開始執行\r\n");
 6         
 7         //延長taskFirst的運行時間
 8         for (UInt32 i = 0; i < loopCountFirst; i++) {
 9             
10         }
11         NSLog(@"taskFirst 任務結束\r\n");
12     };
13     
14     void (^taskSecond)(void) = ^{
15         NSLog(@"taskSecond任務開始執行\r\n");
16         for (UInt32 i = 0; i < loopCount; i ++) {
17             
18         }
19         NSLog(@"taskSecond 任務結束\r\n");
20     };
21     dispatch_queue_t serialQueue;
22     serialQueue = dispatch_queue_create("serialDemo", NULL);
23     //創建第二個隊列
24     dispatch_queue_t serialQueueSecond = dispatch_queue_create("serialSecondDemo", NULL);
25     dispatch_async(serialQueue, taskFirst);
26     NSLog(@"taskfirst 已經加入隊列\r\n");
27     dispatch_async(serialQueueSecond, taskSecond);
28     NSLog(@"tasksecond 已經加入隊列\r\n");

運行得到結果2:

2012-05-14 19:07:22.951 GDCDemo[456:f803] taskfirst 已經加入隊列

2012-05-14 19:07:22.951 GDCDemo[456:11103] taskFirst 任務開始執行

2012-05-14 19:07:22.953 GDCDemo[456:f803] tasksecond 已經加入隊列

2012-05-14 19:07:22.953 GDCDemo[456:12c03] taskSecond任務開始執行

2012-05-14 19:07:22.954 GDCDemo[456:12c03] taskSecond 任務結束

2012-05-14 19:07:22.977 GDCDemo[456:11103] taskFirst 任務結束

由此可見,taskSecond是添加到隊列后立即執行的。兩個串行隊列之間的任務是互不影響的。

 

    並行(Concurrent)

    並行隊列是不允許自己創建的,系統中存在三個不同優先級的並行隊列。並行隊列依舊按照任務添加的順序啟動任務,但是,后一個任務無須等待前一個任務執行完畢,而是啟動第一個任務后,立即啟動下一個任務。至於同一時刻允許同時運行多少個任務有系統決定。任務各自運行在並行隊列為他們提供的獨立線程上,並行隊列中同時運行多少個任務,就必須維護多少個線程。
下面,我們將上一個程序的第21到28行替換為如下代碼:
1 dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2     dispatch_async(concurrentQueue, taskFirst);
3     NSLog(@"taskfirst 已經加入隊列\r\n");
4     dispatch_async(concurrentQueue, taskSecond);
5     NSLog(@"tasksecond 已經加入隊列\r\n");

運行,結果與結果2相同。說明了,taskFirst和taskSecond是同時運行的。

  

    主調度隊列(main dispatch queue)

    主調度隊列中的任務運行在應用程序主線程上,所以,如果你要修改應用程序的界面,他是唯一的選擇。
  演示代碼如下:
   

 dispatch_async(dispatch_get_main_queue(), ^{

        .....//跟新界面的操作

    });

 
 
博客內容是我學習的總結,如果有錯誤,希望大家指出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM