多線程是一個比較輕量級的方法來實現(xiàn)單個應(yīng)用程序內(nèi)多個代碼執(zhí)行路徑。在系統(tǒng)級別內(nèi)怔软,程序并排執(zhí)行冬筒,系統(tǒng)分配到每個程序的執(zhí)行時間是基于該程序的所需時間和其他程序的所需時間來決定的赘风。然而在每個應(yīng)程序的內(nèi)部,存在一個或多個執(zhí)行線程,它同時或在一個幾乎同時發(fā)生的方式里執(zhí)行不同的任務(wù)沐悦。
無論是哪種語言開發(fā)的程序最終往往轉(zhuǎn)換成匯編語言進(jìn)而解釋成機(jī)器碼來執(zhí)行包归。但是機(jī)器碼是按順序執(zhí)行的哄褒,一個復(fù)雜的多步操作只能一步步按順序逐個執(zhí)行矢腻。改變這種狀況可以從兩個角度出發(fā):對于單核處理器敲茄,可以將多個步驟放到不同的線程,這樣一來用戶完成UI操作后其他后續(xù)任務(wù)在其他線程中副签,當(dāng)CPU空閑時會繼續(xù)執(zhí)行遥椿,而此時對于用戶而言可以繼續(xù)進(jìn)行其他操作;對于多核處理器淆储,如果用戶在UI線程中完成某個操作之后冠场,其他后續(xù)操作在別的線程中繼續(xù)執(zhí)行,用戶同樣可以繼續(xù)進(jìn)行其他UI操作本砰,與此同時前一個操作的后續(xù)任務(wù)可以分散到多個空閑CPU中繼續(xù)執(zhí)行(當(dāng)然具體調(diào)度順序要根據(jù)程序設(shè)計而定)碴裙,及解決了線程阻塞又提高了運行效率。
當(dāng)用戶播放音頻点额、下載資源舔株、進(jìn)行圖像處理時往往希望做這些事情的時候其他操作不會被中斷或者希望這些操作過程中更加順暢。在單線程中一個線程只能做一件事情还棱,一件事情處理不完另一件事就不能開始载慈,這樣勢必影響用戶體驗。早在單核處理器時期就有多線程珍手,這個時候多線程更多的用于解決線程阻塞造成的用戶等待(通常是操作完UI后用戶不再干涉办铡,其他線程在等待隊列中,CPU一旦空閑就繼續(xù)執(zhí)行琳要,不影響用戶其他UI操作)寡具,其處理能力并沒有明顯的變化。如今無論是移動操作系統(tǒng)還是PC稚补、服務(wù)器都是多核處理器童叠,于是“并行運算”就更多的被提及。一件事情我們可以分成多個步驟孔厉,在沒有順序要求的情況下使用多線程既能解決線程阻塞又能充分利用多核處理器運行能力。
下圖反映了一個包含8個操作的任務(wù)在一個有兩核心的CPU中創(chuàng)建四個線程運行的情況帖努。假設(shè)每個核心有兩個線程撰豺,那么每個CPU中兩個線程會交替執(zhí)行,兩個CPU之間的操作會并行運算拼余。單就一個CPU而言兩個線程可以解決線程阻塞造成的不流暢問題污桦,其本身運行效率并沒有提高,多CPU的并行運算才真正解決了運行效率問題匙监,這也正是并發(fā)和并行的區(qū)別凡橱。當(dāng)然小作,不管是多核還是單核開發(fā)人員不用過多的擔(dān)心,因為任務(wù)具體分配給幾個CPU運算是由系統(tǒng)調(diào)度的稼钩,開發(fā)人員不用過多關(guān)心系統(tǒng)有幾個CPU顾稀。開發(fā)人員需要關(guān)心的是線程之間的依賴關(guān)系,因為有些操作必須在某個操作完成完才能執(zhí)行坝撑,如果不能保證這個順序勢必會造成程序問題静秆。
多線程原理
有些程序是一條直線,起點到終點巡李;有些程序是一個圓抚笔,不斷循環(huán),直到將它切斷侨拦。直線的如簡單的Hello World殊橙,運行打印完,它的生命周期便結(jié)束了,像曇花一現(xiàn)那樣狱从;圓如操作系統(tǒng)膨蛮,一直運行直到你關(guān)機(jī)。
一個運行著的程序就是一個進(jìn)程或者叫做一個任務(wù)矫夯,一個進(jìn)程至少包含一個線程鸽疾,線程就是程序的執(zhí)行流。Mac和iOS中的程序啟動训貌,創(chuàng)建好一個進(jìn)程的同時制肮, 一個線程便開始運行,這個線程叫主線程递沪。主線程在程序中的地位和其他線程不同豺鼻,它是其他線程最終的父線程,且所有界面的顯示操作即AppKit或 UIKit的操作必須在主線程進(jìn)行款慨。
系統(tǒng)中的每一個進(jìn)程都有自己獨立的虛擬內(nèi)存空間儒飒,而同一個進(jìn)程中的多個線程則共用進(jìn)程的內(nèi)存空間。每創(chuàng)建一個新的線程檩奠,都需要一些內(nèi)存(如每個線程有自己的Stack空間)和消耗一定的CPU時間桩了。另外當(dāng)多個線程對同一個資源出現(xiàn)爭奪的時候需要注意線程安全問題。
關(guān)于 RunLoop