前序:按順序閱讀更好面試
iOS 多線程之GCD服務器
進程:進程是指在系統中正在運行的一個應用程序,如微信、QQ等app都是一個進程.markdown
線程:線程是進程的基本執行單元,處理器調度的基本單位. 一個進程的全部任務都在線程中執行.進程至少要有一條線程,程序啓動會默認開啓一條線程,這條線程被成爲主線程或UI線程網絡
任務: 就是執行操做的意思,換句話說就是你在線程中執行的那段代碼(在 GCD 中是放在 block 中的)。執行任務有兩種方式:同步執行 和 異步執行。二者的主要區別是:是否等待隊列的任務執行結束,以及是否具有開啓新線程的能力。多線程
同步執行(sync):併發
異步執行(async):app
在io等待的時候,同步不會切走,浪費了時間。 若是都是獨佔cpu 的業務, 在單核狀況下 多線和單線 沒有區別。異步
隊列:(Dispatch Queue):這裏的隊列指執行任務的等待隊列,即用來存聽任務的隊列。隊列是一種特殊的線性表,採用 FIFO(先進先出)的原則。GCD 中有兩種隊列串行隊列和併發隊列。二者都符合 FIFO(先進先出)的原則。二者的主要區別是:執行順序不一樣,以及開啓線程數不一樣。
串行隊列(Serial Dispatch Queue):每次只有一個任務被執行。讓任務一個接着一個地執行。(只開啓一個線程,一個任務執行完畢後,再執行下一個任務)
併發隊列(Concurrent Dispatch Queue):可讓多個任務併發(同時)執行。(能夠開啓多個線程,而且同時執行任務)
因此任務和隊列的組合方式有 4 種
隊列/執行 | 併發隊列 | 串行隊列 | 主隊列(特殊的串行隊列) | 全局隊列(特殊的併發隊列) |
---|---|---|---|---|
同步(sync) | 沒有開啓新線程,串行執行任務 | 沒有開啓新線程,串行執行任務 | 死鎖卡住不執行 | 沒有開啓新線程,串行執行任務 |
異步(async) | 有開啓新線程,併發執行任務 | 有開啓新線程,串行執行任務 | 沒有開啓新線程,串行執行任務 | 有開啓新線程,併發執行任務 |
注意
併發隊列的併發功能只有在異步(dispatch_async)方法下才有效。
主隊列是特殊的串行隊列, 全局隊列是特殊的併發隊列(系統提供的)
主隊列的實質上就是一個普通的串行隊列,主線程 中調用 主隊列+同步執行 會致使死鎖問題。 這是由於 主隊列中追加的同步任務 和 主線程自己的任務 二者之間相互等待,阻塞了主隊列,最終形成了主隊列所在的線程(主線程)死鎖問題.
併發(concurrency):把任務在不一樣的時間點交給處理器進行處理。在同一時間點,任務並不會同時運行。
並行(parallelism):把每個任務分配給每個處理器獨立完成。在同一時間點,任務必定是同時運行
單核處理器,多線程只能併發執行(併發原理就是cpu快速來回切換);
多核處理器能夠實現真正的並行,也就是真正的同時運行
既然單核處理器不能實現真正的並行,那麼單核cpu有必要多線程嗎?
一般一個任務不光 cpu 上要花時間,io上也要花時間(例如去數據庫查數據,去抓網頁,讀寫文件等)。一個進程在等 io 的時候,cpu 是閒置的,另外一個進程正好能夠利用 cpu 進行計算。 多個進程一塊兒跑,能夠把 io 和 cpu 都跑滿了。
若是都是獨佔cpu 的業務,在單核狀況下多線程和單線程沒有區別
如今通常都是虛擬資源,資源有彈縮機制,因此通常該跑多線程的時候就能夠跑多線程
1.在多核處理器上,將要執行的任務分紅多個可並行執行的線程,就能夠提升執行效率。
2.在單核處理器上,多線程只能併發執行,而不是並行,併發原理,其實就是cpu快速來回切換,在特定的時間執行特定的某一個任務,併發執行存在這線程間上下文切換的問題,會消耗必定的時間。若是不考慮阻塞,多線程併發執行其實比單線程執行更加耗費時間,線程過多也會形成cpu負荷過大,而且線程佔用內存資源,建立銷燬線程也都是須要開銷的。
多線程經過提升cpu利用率來提升效率。數據庫訪問、磁盤io等操做的速度比cpu執行代碼的速度慢不少,單線程環境下,這些操做會阻塞程序的執行,致使cpu空轉,等待着上述操做完成,所以對於會產生這些阻塞的程序來講,使用多線程能夠避免在等待期間cpu的空轉,提升cpu的利用率。
考慮到多線程存在的一些缺點,如今的網絡服務器爲了支持大量併發多不是靠多線程或多進程,而採用其餘的技術如異步i/o