最近在寫關於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



.png)


.png)

沒有留言:
張貼留言