前言
最近iOS開發(fā)群里兄弟們討論網(wǎng)絡(luò)層這塊的東西比較多谒麦,問題主要集中在請求、線程哆致、隊(duì)列這幾塊绕德。中途發(fā)現(xiàn)對并發(fā)、異步摊阀、多線程等這些概念有一定的誤解耻蛇,特寫此篇文章以作闡釋坡贺。
這篇文章就主要會(huì)講這些方面:
- 幾個(gè)概念的字面意義
- 幾個(gè)概念的詳細(xì)理解
- 總結(jié)
幾個(gè)概念的字面意義
并發(fā):在操作系統(tǒng)中堤尾,是指一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一個(gè)處理機(jī)上運(yùn)行迹辐,但任一個(gè)時(shí)刻點(diǎn)上只有一個(gè)程序在處理機(jī)上運(yùn)行鹅经。
并行:一組程序按獨(dú)立異步的速度執(zhí)行桐罕,不等于時(shí)間上的重疊(同一個(gè)時(shí)刻發(fā)生)该面。
同步:指兩個(gè)或兩個(gè)以上隨時(shí)間變化的量在變化過程中保持一定的相對關(guān)系副渴。
異步:異步雙方不需要共同的時(shí)鐘,也就是接收方不知道發(fā)送方什么時(shí)候發(fā)送刁赦,所以在發(fā)送的信息中就要有提示接收方開始接收的信息娶聘,如開始位,同時(shí)在結(jié)束時(shí)有停止位截型。
多線程:是指從軟件或者硬件上實(shí)現(xiàn)多個(gè)線程并發(fā)執(zhí)行的技術(shù)。具有多線程能力的計(jì)算機(jī)因有硬件支持而能夠在同一時(shí)間執(zhí)行多于一個(gè)線程儒溉,進(jìn)而提升整體處理性能宦焦。
阻塞:是指程序調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起(線程進(jìn)入非可執(zhí)行狀態(tài)顿涣,在這個(gè)狀態(tài)下波闹,CPU不會(huì)給線程分配時(shí)間片,即線程暫停運(yùn)行)涛碑。函數(shù)只有在得到結(jié)果之后才會(huì)返回精堕。
非阻塞:指在不能立刻得到函數(shù)運(yùn)行結(jié)果之前,該函數(shù)不會(huì)阻塞當(dāng)前線程蒲障,而會(huì)立刻返回歹篓。
幾個(gè)概念的應(yīng)用領(lǐng)域
以上幾個(gè)概念的字面意思請大家看上三遍。然后按照字面意思來個(gè)配對揉阎。
- [并發(fā)庄撮、并行]
- [同步、異步]
- [阻塞毙籽、非阻塞]
- 多線程
并發(fā)
并發(fā)大家肯定平時(shí)經(jīng)常提及洞斯,不管是app、web server并發(fā)無處不在坑赡。仔細(xì)看上面并發(fā)的字面意思烙如,是指一個(gè)時(shí)間段內(nèi)多個(gè)程序(任務(wù))同時(shí)處于運(yùn)行活動(dòng)狀態(tài),而不是在某一個(gè)時(shí)間點(diǎn)上都處于運(yùn)行狀態(tài)毅否。參與并發(fā)的程序(任務(wù))都是串行執(zhí)行的亚铁,所以不存在同時(shí)刻執(zhí)行多個(gè)程序(任務(wù))的情況。那問題來了螟加,為什么咱們平時(shí)編碼的過程中發(fā)現(xiàn)多個(gè)任務(wù)都是同時(shí)執(zhí)行的呢刀闷?因?yàn)橛邢到y(tǒng)時(shí)間片輪轉(zhuǎn)的參與熊泵,操作系統(tǒng)通過將cpu的執(zhí)行時(shí)間分割成多個(gè)時(shí)間片,為每個(gè)程序(任務(wù))分配時(shí)間片甸昏,因?yàn)閏pu處理速度很快顽分,這樣就有了看起來好像每個(gè)任務(wù)都在同時(shí)執(zhí)行的宏觀感受,感覺有多個(gè)cpu施蜜,但本質(zhì)上一個(gè)時(shí)間點(diǎn)只有一個(gè)程序(任務(wù))在運(yùn)行卒蘸。
并行
而相對并發(fā),并行可能陌生了不少翻默,或許咱們還會(huì)會(huì)當(dāng)做同一個(gè)概念來理解缸沃。雖然并行有和并發(fā)相同的外部特征,但是內(nèi)部實(shí)現(xiàn)是不一樣的修械。而且并行的原理也比并發(fā)簡單趾牧,籠統(tǒng)的說就是套物理硬件的堆砌來實(shí)現(xiàn),通過增加cpu核心來實(shí)現(xiàn)多個(gè)程序(任務(wù))的同時(shí)進(jìn)行肯污。是的翘单,是并行做到了多任務(wù)的同時(shí)執(zhí)行。
同步
在多個(gè)邏輯調(diào)用間有一定的時(shí)間關(guān)系蹦渣,就好比拿出鑰匙才能去開門哄芜。前一個(gè)邏輯調(diào)用的輸出作為第二個(gè)邏輯調(diào)用的輸入,后一個(gè)邏輯調(diào)用必須等待前一個(gè)調(diào)用執(zhí)行完才能開始調(diào)起執(zhí)行柬唯。這個(gè)很好理解认臊。
異步
正好與同步相反,后一個(gè)邏輯調(diào)用無需等待前一個(gè)邏輯調(diào)用執(zhí)行完畢锄奢。也就是說前一個(gè)邏輯調(diào)用發(fā)起后就直接返回了失晴,并沒有輸出,而是在調(diào)用執(zhí)行完成后通過狀態(tài)拘央、通知來通知調(diào)用者师坎,或通過回調(diào)函數(shù)處理這個(gè)調(diào)用。
阻塞
是指調(diào)用輸出之前堪滨,當(dāng)前線程會(huì)被掛起胯陋。調(diào)用線程只有在得到結(jié)果之后才會(huì)返回。
非阻塞
指在不能立刻返回調(diào)用輸出之前袱箱,該調(diào)用不會(huì)阻塞當(dāng)前線程遏乔。
多線程
線程,有時(shí)被稱為輕量級(jí)進(jìn)程(Lightweight Process发笔,LWP)盟萨,是程序執(zhí)行流的最小單元。在我看來了讨,線程就是程序(任務(wù))的執(zhí)行載體捻激,多線程則是并發(fā)的具體邏輯實(shí)現(xiàn)制轰。所以,多線程就是并發(fā)胞谭,這個(gè)觀念是錯(cuò)誤了垃杖,兩個(gè)領(lǐng)域的東西,這個(gè)不難理解丈屹。
總結(jié)
此刻大家應(yīng)該能區(qū)分并發(fā)和并行了吧调俘。對于并發(fā)和并行理解停留在概念階段就可以,具體系統(tǒng)層面如何實(shí)現(xiàn)旺垒,只需了解即可彩库。比較形象的比喻就是單車道和多車道。除去并發(fā)和并行先蒋,其他幾個(gè)概念都是我們平時(shí)編碼過程中經(jīng)常用到的骇钦。多線程剛才說了是并發(fā)的代碼邏輯實(shí)現(xiàn),同步和異步是指邏輯調(diào)用方式竞漾,而阻塞和非阻塞則主要強(qiáng)調(diào)邏輯調(diào)用當(dāng)前的狀態(tài)眯搭。有同學(xué)可能會(huì)問并發(fā)和同步、異步有什么關(guān)系嗎畴蹭?明確的說沒有關(guān)系坦仍,完全是兩個(gè)領(lǐng)域的東西鳍烁。也有同學(xué)會(huì)認(rèn)為異步就是多線程叨襟,仔細(xì)看上面的解釋,相信一定能明白幔荒。在開發(fā)過程中完全可以把并發(fā)和并行兩個(gè)概念拋到腦后糊闽,因?yàn)樾薷牟l(fā)和并行是靠修改系統(tǒng)層面配置或者提升硬件來解決,對于應(yīng)用開發(fā)者爹梁,無需關(guān)心右犹。
好了,現(xiàn)在再去看AFNetworking的源碼姚垃,你是不是能理解AFNetworking處理多個(gè)請求只用了一個(gè)線程念链,給我們的感覺卻是多個(gè)請求同時(shí)處理的呢?
廢話有點(diǎn)多积糯,大家勿噴啊掂墓,不對的地方希望能夠幫忙指正(包括行文方面的問題)。