最近在寫關於PDF的SDK才知道GCD很重要而且常用,平行還真難寫,網路上教學實在很多,瞭解後還是要把寫的樣板背起來,所以先簡單記錄一些平行的樣板八!!
GCD-queue的類型:
queue type | describe |
---|---|
Main queue | main queue工作會依序執行,iOS的UI都是由main thread控制 |
concurrent queue | 還是會依照FIFO的方式來執行,但是有可能後執行的block比先執行的先完成 |
serial queue | 會採用一個接一個的方式來依序執行block |
1. All mainThread:此樣板在於把某些task(block)放到main queue,所有的task都在main thread執行
- (IBAction)GCDTest1Btn:(id)sender { mainQueue = dispatch_get_main_queue(); void (^block1) (void) = ^{ for(int i = 0;i<10;i++){ NSLog(@"some block is execute %d time.",i); } }; void (^block2) (void) = ^{ for(int i=0;i<10;i++){ NSLog(@"The other block is execute %d time.",i); } }; NSLog(@"First block"); dispatch_async(mainQueue, block1); NSLog(@"Second block"); dispatch_async(mainQueue, block2); }
因為用的是dispatch_async執行,所以執行完dispatch_async會把block加到main queue後面然後緊接著執行NSLog
上面程式碼執行的示意圖:
執行結果:
2. global queue template:global queue通常是concurrent的queue,搭配dispatcy_async使用
- (IBAction)GCDTest2Btn:(id)sender { globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); void (^block1) (void) = ^{ for(int i = 0;i<10;i++){ NSLog(@"some block is execute %d time.",i); } }; void (^block2) (void) = ^{ for(int i=0;i<10;i++){ NSLog(@"The other block is execute %d time.",i); } }; NSLog(@"First block"); dispatch_async(globalQueue, block1); NSLog(@"Second block"); dispatch_async(globalQueue, block2); }
執行結果:
3. 自己定義的queue:該queue的做法是會再開一個thread,然後task會依照該queue在另外的thread執行
- (IBAction)GCDTest3Btn:(id)sender { myQueue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL); void (^block1) (void) = ^{ for(int i = 0;i<10;i++){ NSLog(@"some block is execute %d time.",i); } }; void (^block2) (void) = ^{ for(int i=0;i<10;i++){ NSLog(@"The other block is execute %d time.",i); } }; NSLog(@"First block"); dispatch_async(myQueue, block1); NSLog(@"Second block"); dispatch_async(myQueue, block2); }
上面的code在會在執行完dispatch_async後緊接著執行NSLog,不會造成阻礙,然後block1和block2會在另外thread執行
上面程式碼執行的示意圖:
執行結果:
4. 一些要避免的deadlock template:寫平行需要小心的就是deadlock,記錄下template
a. queue為main queue:
- (IBAction)GCDTest4Btn:(id)sender { mainQueue = dispatch_get_main_queue(); void (^block1) (void) = ^{ NSLog(@"block1"); }; NSLog(@"in main thread"); dispatch_sync(mainQueue, block1); }
在上面的程式碼當中,因為使用的是dispatch_sync,其中sync會等該queue中前面的task做完,才能往下繼續執行。 因為共同使用main queue,所以原本的function "GCDTest4Btn" action在main thread上執行,所以task在queue中比block1前面,又因為使用dispatch_sync,所以"GCDTest4Btn" action會等待block1的task完成,然而在queue中,因為是以serial的方式進行,block1在"GCDTest4Btn" action之後,所以會等待該action執行完畢,造成兩個task互相等待,形成deadlock
執行結果:
b. queue為自定的queue
- (IBAction)GCDTest5Btn:(id)sender { myQueue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL); NSLog(@"in main queue"); void (^block1) (void) = ^{ NSLog(@"block1"); }; void (^block2) (void) = ^{ NSLog(@"block2"); dispatch_sync(myQueue, block1); }; NSLog(@"in block1"); dispatch_sync(myQueue, block1); NSLog(@"in block2"); dispatch_sync(myQueue, block2); }
上面的程式碼概念同a,示意圖如下:
執行結果:
myCode
沒有留言:
張貼留言