標籤:並發 解決 create sign time hub 術語 name 同步
講解GCD的資料看了好多,但都沒有解決心中的疑惑:
1.主隊列只有一個線程,那麼同步和非同步執行有什麼區別?同步主線程會造成線程死結,非同步不會,為什麼呢?
2.同步執行串列隊列和同步執行並行隊列,有什麼區別?同步執行,是在當前線程中執行隊列中的任務,就意味著任務都在一條線程中執行,不可能多任務同時執行啊。
3.在主線程中同步執行串列隊列,為什麼就不造成線程死結呢?
有疑不解,如鯁在喉。有疑惑就代表學得不到位,概念理解不夠。因此,我開始重頭學習GCD,理清這些基礎概念。
有4個術語比較容易混淆:同步、非同步、並發、串列
同步和非同步決定了要不要開啟新的線程
同步:在當前線程中執行任務,不具備開啟新線程的能力
非同步:在新的線程中執行任務,具備開啟新線程的能力
並發和串列決定了任務的執行方式
並發:多個任務並發(同時)執行
串列:一個任務執行完畢後,再執行下一個任務
組合一下:
- 同步執行串列隊列
- 同步執行並發隊列
- 非同步執行串列隊列
- 非同步執行並發隊列
- 同步執行主隊列
- 非同步執行主隊列
我加入了主隊列(只有一條線程的串列隊列),是因為它和一般的串列隊列有些區別。下面我就對這6種情況逐個分析。
1.同步執行串列隊列:在當前線程中,逐一執行隊列中的任務。
2.同步執行並發隊列:同1
3.非同步執行串列隊列:開啟一條新線程,逐一執行隊列中的任務。
4.非同步執行並發隊列:開啟多條線程,同時執行隊列中的多個任務。
先理清這四種情況的嵌套執行,在講主線的兩種情況。
下面就是大堆代碼了,對照代碼和列印結果進行思考,看有沒有自己覺得解釋不通的。
demo地址:https://github.com/jiliuliu/FoundationOC
int main(int argc, const char * argv[]) { @autoreleasepool { dispatch_queue_t backgroundSerialQueue = dispatch_queue_create("backgroundSerialQueue", DISPATCH_QUEUE_SERIAL); dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL); dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT); //避開主線程,單獨開啟一個線程做測試 dispatch_async(backgroundSerialQueue, ^{ NSLog(@"%@", [NSThread currentThread]); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)1"); }); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)2"); }); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)3"); }); NSLog(@"************************"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)1"); }); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)2"); }); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)3"); }); }); } NSLog(@"----exit----"); return 0;}
列印結果:
----exit----<NSThread: 0x10064f1b0>{number = 2, name = (null)}
感覺和預想的那裡不對,於是修改下:
int main(int argc, const char * argv[]) { @autoreleasepool { dispatch_queue_t backgroundSerialQueue = dispatch_queue_create("backgroundSerialQueue", DISPATCH_QUEUE_SERIAL); dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL); dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT); //避開主線程,單獨開啟一個線程做測試 dispatch_async(backgroundSerialQueue, ^{ NSLog(@"%@", [NSThread currentThread]); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)1"); }); NSLog(@"dispatch_sync(serialQueue)1--"); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)2"); }); NSLog(@"dispatch_sync(serialQueue)2--"); dispatch_sync(serialQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(serialQueue)3"); }); NSLog(@"dispatch_sync(serialQueue)3--"); NSLog(@"************************"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)1"); }); NSLog(@"ispatch_sync(concurrentQueue)1--"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)2"); }); NSLog(@"ispatch_sync(concurrentQueue)2--"); dispatch_sync(concurrentQueue, ^{ [NSThread sleepForTimeInterval:0.01]; NSLog(@"dispatch_sync(concurrentQueue)3"); }); NSLog(@"ispatch_sync(concurrentQueue)3--"); dispatch_barrier_sync(serialQueue, ^{ dispatch_semaphore_signal(semaphore); }); dispatch_barrier_sync(concurrentQueue, ^{ dispatch_semaphore_signal(semaphore); }); }); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); } NSLog(@"----exit----"); return 0;}
列印結果:
<NSThread: 0x100600170>{number = 2, name = (null)}dispatch_sync(serialQueue)1dispatch_sync(serialQueue)1--dispatch_sync(serialQueue)2dispatch_sync(serialQueue)2--dispatch_sync(serialQueue)3dispatch_sync(serialQueue)3--************************dispatch_sync(concurrentQueue)1ispatch_sync(concurrentQueue)1--dispatch_sync(concurrentQueue)2ispatch_sync(concurrentQueue)2--dispatch_sync(concurrentQueue)3ispatch_sync(concurrentQueue)3------exit----
對,就應該是這樣的。
5.同步執行主隊列:
6.非同步執行主隊列:
iOS--關於GCD的一些疑惑