背景
首先,處理器的速度對用戶體驗至關重要,是開發者不可忽視的問題,隨著時代的進步,處理器速度的提升,對開發者來說意味著更廣闊的自由發揮空間。每一代的新硬件都能是代碼的速度運行更快,處理器每年都會變得越開越強大,一方面是速度更快,另一方面是具有更好的并行性。多CPU,多處理器計算機的普及使非常小的設備也擁有了多核CPU。增加了并發性,提高了程序的運行效率。
GCD與多線程
1,多線程
線程是操作系統能夠進行運算調度的最小單位。那多線程是如何實現的呢?實際上,每個線程會被分配給一個時間段,稱為時間片,即進程允許運行的時間。如果時間片結束時進程還在運行,CPU將會剝奪并分派給另外一個進程;如果進程在時間片沒有結束前阻塞或是結束,則CPU進行切換。從而不會造成CPU資源的浪費,使得程序看上去是同時進行的。
那么線程是越多越好嗎?其實并不是。1,線程的創建和維護成本很高,所以設計使用線程的軟件一般會引入少量或中等數量的長期存在的線程。這些線程執行重量級的操作,比如網絡操作,數據庫操作或者計算。因為這些操作涉及面很廣,訪問需要大量的輸入和輸出,那就意味著要加鎖。枷鎖的代價昂貴,還可能導致大量的BUG。管理線程還需要一個線程池,需要自己去管理。2,每個進程都有自己虛有的地址空間,進程里的所有線程共享同一地址空間。每個線程都要占用內存,多線程就意味著更多的內存資源被占用。
2,GCD
首先,GCD是隊列不是線程,是iOS多任務的核心,多任務最基本的形式就是運行循環。每個COCOA應用程序都是由一個do/While循環驅動,當有事件發生時,就把事件分派給合適的監聽器,如此反復直到循環停止。處理分派的對象就叫做運行循環,它運行在某個線程中,從各種事件隊列中取得事件,然后把它分派給合適的監聽器。
每個線程都有一個運行循環,但并不是說每個線程都會處理自己的運行循環。運行循環僅在需要對runUntileDate等命令做出響應時,才會執行他的do/While循環。調用main.M 文件中的UIApplicationMain就會運行循環。
NSOperationQueue 是操作隊列,操作支持優先級,依賴關系和取消。每個單元會創建幾個操作,所有單元的操作會被放進同一個隊列。
GCD 屬于分派隊列,分派隊列是把一個塊添加到分派隊列,而不是把NSOperation添加到NSOperationQueue,分派隊列不操作隊列更底層,塊添加到分派隊列后就無法取消,是嚴格的先進先出結構。GCD大致可以分為三類?
1,dispatch_async 并行隊列 2,dispatch_sync 串行隊列 3,自定義隊列 DISPATCH_QUEUE_SERIAL 順序執行 和 DISPATCH_QUEUE_CONCURRENT并發執行
GCD 隊列擁有優先級,可用全局系統隊列dispatch_get_global_queue和優先級來訪問某個隊列
#define DISPATCH_QUEUE_PRIORITY_HIGH?
#define DISPATCH_QUEUE_PRIORITY_DEFAULT?
#define DISPATCH_QUEUE_PRIORITY_LOW?
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND?
GCD 會根據可用線程從高優先級隊列到低優先級隊列調度塊。系統會根據可用核心數和負載按需創建和銷毀線程。
GCD 可以用很低的開銷解決鎖的問題 。分派屏障 dispatch barrier 可以在并發隊列內部創建一個同步點,當他運行時,即使有并發的條件和空閑的處理器核心,隊列中的其他快也不能運行。這可以看做互斥鎖(寫入鎖),沒有屏障的塊可以看做共享鎖(讀取鎖)。只要對資源的訪問是通過這個隊列 進行的,那么屏障就能以極低的代價提供同步。