多線程——GCD

 1、 GCD的基本概念

  • GCD:強大的中樞調度,純C語言,提供了很是多強大的函數。
  • 任務(block):執行什麼操做。
  • 隊列(queue):用來存聽任務。
  • 同步函數dispatch_sync():不建立新線程,在當前線程中順序執行隊列裏的任務。
  • 異步函數dispatch_async():建立新線程,在另外一條線程中執行隊列裏的任務。
  • 串行隊列:任務一個接着一個有序的執行。
  • 併發隊列:讓多個任務併發(同時)執行。

 

2、 隊列

1. GCD中得到串行有2種途徑併發

(1)使用dispatch_queue_create函數建立串行隊列異步

(2)使用主隊列(跟主線程相關聯的隊列)async

// 手動建立
dispatch_queue_t queue = dispatch_queue_create("wendingding", NULL); 

// 得到主線程,主線程就是串行隊列
dispatch_queue_t queue = dispatch_get_main_queue();

 

2. 得到併發隊列函數

(1)使用dispatch_get_global_queue函數得到全局的併發隊列spa

// 無需手動建立,從中樞調度系統中獲取
ispatch_queue_t dispatch_get_global_queue((DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

 

 (2)全局併發隊列的優先級線程

  • #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
  • #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(中)
  • #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
  • #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 後臺

 

3、 GCD的應用

1. 同步:code

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     // Do any additional setup after loading the view, typically from a nib.
 4     
 5     
 6     // 1. 建立串行隊列
 7     dispatch_queue_t sQueue = dispatch_queue_create("sQueue", 0);
 8     
 9     // 2. 把3個任務加入串行隊列,同步函數中執行
10     dispatch_sync(sQueue, ^{
11         NSLog(@"load1---%@", [NSThread currentThread]);
12     });
13     
14     dispatch_sync(sQueue, ^{
15         NSLog(@"load2---%@", [NSThread currentThread]);
16     });
17     
18     dispatch_sync(sQueue, ^{
19         NSLog(@"load3---%@", [NSThread currentThread]);
20     });
21     
22     // 主線程,主線程是在同步函數中執行的
23     NSLog(@"main---%@", [NSThread mainThread]);
24     
25 }

第一次運行結果:blog

2016-10-30 00:11:32.711 06-GCD[20831:12214875] load1---<NSThread: 0x7b74e5a0>{number = 1, name = main}
2016-10-30 00:11:32.711 06-GCD[20831:12214875] load2---<NSThread: 0x7b74e5a0>{number = 1, name = main}
2016-10-30 00:11:32.712 06-GCD[20831:12214875] load3---<NSThread: 0x7b74e5a0>{number = 1, name = main}
2016-10-30 00:11:32.712 06-GCD[20831:12214875] main---<NSThread: 0x7b74e5a0>{number = 1, name = main}

 

第二次運行結果:隊列

2016-10-30 00:15:40.913 06-GCD[20865:12237365] load1---<NSThread: 0x7e202070>{number = 1, name = main}
2016-10-30 00:15:40.913 06-GCD[20865:12237365] load2---<NSThread: 0x7e202070>{number = 1, name = main}
2016-10-30 00:15:40.914 06-GCD[20865:12237365] load3---<NSThread: 0x7e202070>{number = 1, name = main}
2016-10-30 00:15:40.914 06-GCD[20865:12237365] main---<NSThread: 0x7e202070>{number = 1, name = main}

 

註解:由以上兩次運行結果可知,同步函數不會建立新線程,故以上程序都是在默認線程,即主線程中執行,同步函數內的程序都是按順序執行的。get

 

2. 異步:

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     // Do any additional setup after loading the view, typically from a nib.
 4     
 5     // 1. 得到併發隊列
 6     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 7     
 8     // 2. 開3個線程,把3個任務加入隊列,異步執行
 9     dispatch_async(queue, ^{
10         NSLog(@"load1---%@", [NSThread currentThread]);
11     });
12     
13     dispatch_async(queue, ^{
14         NSLog(@"load2---%@", [NSThread currentThread]);
15     });
16     
17     dispatch_async(queue, ^{
18         NSLog(@"load3---%@", [NSThread currentThread]);
19     });
20     
21     NSLog(@"main---%@", [NSThread mainThread]);
22     
23 }

第一次運行結果:

2016-10-29 23:52:18.519 06-GCD[20685:12129480] load1---<NSThread: 0x79979100>{number = 3, name = (null)}
2016-10-29 23:52:18.519 06-GCD[20685:12129482] load2---<NSThread: 0x79676d10>{number = 4, name = (null)}
2016-10-29 23:52:18.520 06-GCD[20685:12129504] load3---<NSThread: 0x799782d0>{number = 5, name = (null)}
2016-10-29 23:52:18.519 06-GCD[20685:12129446] main---<NSThread: 0x7996f180>{number = 1, name = main}

第二次運行結果:

2016-10-29 23:56:40.791 06-GCD[20734:12158067] main---<NSThread: 0x79f15640>{number = 1, name = main}
2016-10-29 23:56:40.791 06-GCD[20734:12158259] load3---<NSThread: 0x79f2bc90>{number = 5, name = (null)}
2016-10-29 23:56:40.791 06-GCD[20734:12158262] load1---<NSThread: 0x7b8284a0>{number = 3, name = (null)}
2016-10-29 23:56:40.791 06-GCD[20734:12158260] load2---<NSThread: 0x79e247e0>{number = 4, name = (null)}

第三次運行結果:

2016-10-29 23:57:12.016 06-GCD[20751:12162437] load1---<NSThread: 0x7b61ead0>{number = 3, name = (null)}
2016-10-29 23:57:12.016 06-GCD[20751:12162440] load3---<NSThread: 0x7d9113a0>{number = 5, name = (null)}
2016-10-29 23:57:12.016 06-GCD[20751:12162438] load2---<NSThread: 0x7d822fa0>{number = 4, name = (null)}
2016-10-29 23:57:12.016 06-GCD[20751:12162185] main---<NSThread: 0x7d809fc0>{number = 1, name = main}

 

註解:由運行結果可看出,異步函數會建立出3個新線程,併發隊列裏的任務不是按照順序執行的,而是隨機併發執行的。

總結:

  • 併發隊列只有放到異步函數裏面執行才能獲得併發的效果,即放到併發隊列裏的任務,不按照順序,隨機併發執行的。
  • 併發隊列若是放到同步函數裏面執行,跟串行隊列放到同步函數裏面執行的效果是同樣的,順序執行。
  • 同步隊列放到異步函數裏面執行,則隊列裏的任務都是順序執行的。
相關文章
相關標籤/搜索