概念
為了在單一進程中充分發(fā)揮多核的優(yōu)勢,我們有必要使用多線程技術(shù)(我們沒必要去提多進程,這玩意兒和GCD沒關(guān)系)。在低層,GCD全局dispatch queue僅僅是工作線程池的抽象。這些隊列中的Block一旦可用,就會被dispatch到工作線程中。提交至用戶隊列的Block最終也會通過全局隊列進入相同的工作線程池(除非你的用戶隊列的目標是主線程,但是為了提高運行速度,我們絕不會這么干)。
有兩種途徑來通過GCD“榨取”多核心系統(tǒng)的性能:將單一任務或者一組相關(guān)任務并發(fā)至全局隊列中運算;將多個不相關(guān)的任務或者關(guān)聯(lián)不緊密的任務并發(fā)至用戶隊列中運算;
全局隊列
設(shè)想下面的循環(huán):
for(id obj in array)
[self doSomethingIntensiveWith:obj];
假定-doSomethingIntensiveWith:是線程安全的且可以同時執(zhí)行多個.一個array通常包含多個元素,這樣的話,我們可以很簡單地使用GCD來平行運算:
dispatch_queue_t
queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
for(idobj
in array)
dispatch_async(queue,
^{
[selfdoSomethingIntensiveWith:obj];
});
如此簡單,我們已經(jīng)在多核心上運行這段代碼了。
當然這段代碼并不完美。有時候我們有一段代碼要像這樣操作一個數(shù)組,但是在操作完成后,我們還需要對操作結(jié)果進行其他操作:
for(id obj in array)
[self doSomethingIntensiveWith:obj];
[self doSomethingWith:array];
這時候使用GCD的dispatch_async就悲劇了.我們還不能簡單地使用dispatch_sync來解決這個問題, 因為這將導致每個迭代器阻塞,就完全破壞了平行計算。
解決這個問題的一種方法是使用dispatch group。一個dispatch group可以用來將多個block組成一組以監(jiān)測這些Block全部完成或者等待全部完成時發(fā)出的消息。使用函數(shù)dispatch_group_create來創(chuàng)建,然后使用函數(shù)dispatch_group_async來將block提交至一個dispatch queue,同時將它們添加至一個組。所以我們現(xiàn)在可以重新編碼:
dispatch_queue_t
queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0);
dispatch_group_t
group = dispatch_group_create();
for(idobj
in array)
dispatch_group_async(group,
queue, ^{
[selfdoSomethingIntensiveWith:obj];
});
dispatch_group_wait(group,
DISPATCH_TIME_FOREVER);
dispatch_release(group);
[self doSomethingWith:array];
如果這些工作可以異步執(zhí)行,那么我們可以更風騷一點,將函數(shù)-doSomethingWith:放在后臺執(zhí)行。我們使用dispatch_group_async函數(shù)建立一個block在組完成后執(zhí)行: