線程與進(jìn)程的區(qū)別以及對多線程并發(fā)的理解
一、線程與進(jìn)程的區(qū)別
先簡單說說線程與進(jìn)程的概念:
(1)進(jìn)程是指一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序,比如在Windows系統(tǒng)中,一個(gè)運(yùn)行的exe就是一個(gè)進(jìn)程。
(2)線程是指進(jìn)程中的一個(gè)執(zhí)行流程。
區(qū)別:
一個(gè)程序至少有一個(gè)進(jìn)程,而一個(gè)進(jìn)程至少有一個(gè)線程。一個(gè)應(yīng)用程序可以同時(shí)啟動多個(gè)進(jìn)程。例如對于IE瀏覽器程序,每打開一個(gè)IE瀏覽器窗口,就啟動了一個(gè)新的進(jìn)程。而線程則是指進(jìn)程中的一個(gè)執(zhí)行流程,一個(gè)進(jìn)程可以有多個(gè)線程,每個(gè)線程分別執(zhí)行不同的任務(wù),當(dāng)進(jìn)程內(nèi)的多個(gè)線程同時(shí)運(yùn)行時(shí),這種運(yùn)行方式就被稱為并發(fā)運(yùn)行。
另外,線程與進(jìn)程還有一個(gè)非常重要的區(qū)別:每個(gè)進(jìn)程在執(zhí)行過程中都擁有獨(dú)立的內(nèi)存單元,而同一個(gè)進(jìn)程中的多個(gè)線程則共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率。
二、對多線程并發(fā)的理解
多線程并發(fā)只是表面和感覺上的并發(fā),并不是實(shí)質(zhì)上的并發(fā)。一個(gè)線程要運(yùn)行,它必須占有CPU,而我們目前用的計(jì)算機(jī)大多都是單CPU的,所以一次最多只能有一個(gè)線程獲取CPU并運(yùn)行。
多線程的實(shí)質(zhì)是“***限度地利用CPU資源”,當(dāng)某一個(gè)線程的處理不需要占用CPU而只需要和I/O等資源打交道時(shí),讓其他線程有機(jī)會獲得CPU資源。這有點(diǎn)類似于“統(tǒng)籌方法”,例如讓你打掃房子和燒水,要在最短的時(shí)間內(nèi)做好這兩件事,你一定會想到先把水燒上,然后在等水燒開的空閑時(shí)間中去打掃房子,而不是先打掃好了再去燒水,也不是先燒好了再去打掃,這個(gè)例子里面,你是那個(gè)唯一的CPU,而燒水和打掃就是兩個(gè)線程。
雖然CPU只有一個(gè),但是它在多個(gè)線程之間頻繁切換,當(dāng)切換的頻率高到一定程度時(shí),我們就感覺所有的線程在同時(shí)運(yùn)行,于是感覺這多個(gè)線程是并發(fā)的。因此,并發(fā)并不是真的指多個(gè)線程同時(shí)運(yùn)行,它僅僅只是形容一種現(xiàn)象。就好像說有些人是“鐵人”一樣,僅僅只是用于形容某個(gè)人不怕苦不怕累,像個(gè)“鐵人”。
1. 并發(fā):在操作系統(tǒng)中,是指一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一個(gè)處理機(jī)上運(yùn)行。其中兩種并發(fā)關(guān)系分別是同步和互斥
2. 互斥:進(jìn)程間相互排斥的使用臨界資源的現(xiàn)象,就叫互斥。
3. 同步:進(jìn)程之間的關(guān)系不是相互排斥臨界資源的關(guān)系,而是相互依賴的關(guān)系。進(jìn)一步的說明:就是前一個(gè)進(jìn)程的輸出作為后一個(gè)進(jìn)程的輸入,當(dāng)***個(gè)進(jìn)程沒有輸出時(shí)第二個(gè)進(jìn)程必須等待。具有同步關(guān)系的一組并發(fā)進(jìn)程相互發(fā)送的信息稱為消息或事件。
其中并發(fā)又有偽并發(fā)和真并發(fā),偽并發(fā)是指單核處理器的并發(fā),真并發(fā)是指多核處理器的并發(fā)。
4. 并行:在單處理器中多道程序設(shè)計(jì)系統(tǒng)中,進(jìn)程被交替執(zhí)行,表現(xiàn)出一種并發(fā)的外部特種;在多處理器系統(tǒng)中,進(jìn)程不僅可以交替執(zhí)行,而且可以重疊執(zhí)行。在多處理器上的程序才可實(shí)現(xiàn)并行處理。從而可知,并行是針對多處理器而言的。并行是同時(shí)發(fā)生的多個(gè)并發(fā)事件,具有并發(fā)的含義,但并發(fā)不一定并行,也亦是說并發(fā)事件之間不一定要同一時(shí)刻發(fā)生。
5. 多線程:多線程是程序設(shè)計(jì)的邏輯層概念,它是進(jìn)程中并發(fā)運(yùn)行的一段代碼。多線程可以實(shí)現(xiàn)線程間的切換執(zhí)行。
6. 異步:異步和同步是相對的,同步就是順序執(zhí)行,執(zhí)行完一個(gè)再執(zhí)行下一個(gè),需要等待、協(xié)調(diào)運(yùn)行。異步就是彼此獨(dú)立,在等待某事件的過程中繼續(xù)做自己的事,不需要等待這一事件完成后再工作。線程就是實(shí)現(xiàn)異步的一個(gè)方式。異步是讓調(diào)用方法的主線程不需要同步等待另一線程的完成,從而可以讓主線程干其它的事情。
異步和多線程并不是一個(gè)同等關(guān)系,異步是最終目的,多線程只是我們實(shí)現(xiàn)異步的一種手段。異步是當(dāng)一個(gè)調(diào)用請求發(fā)送給被調(diào)用者,而調(diào)用者不用等待其結(jié)果的返回而可以做其它的事情。實(shí)現(xiàn)異步可以采用多線程技術(shù)或則交給另外的進(jìn)程來處理。
為了對以上概念的更好理解舉一個(gè)簡單例子, 假設(shè)我要做 燒開水,舉杠鈴100下, 洗衣服 3件事情。
燒開水 這件事情, 我要做的事情為, 準(zhǔn)備燒開水 1分鐘, 等開水燒開 8 分鐘 , 關(guān)掉燒水機(jī) 1分鐘
舉杠鈴100下 我要做的事情為, 舉杠鈴100下 10分鐘
洗衣服 我要做的事情為, 準(zhǔn)備洗衣服 1分鐘, 等開水燒開 5 分鐘 , 關(guān)掉洗衣機(jī) 1分鐘
單核情況下
同步的完成,我需要做的時(shí)間為 1+ 8 +1 + 10 + 1+ 5 +1 = 27 分
如果異步,就是在等的時(shí)候,我可以切換去做別的事情
準(zhǔn)備燒開水(1) + 準(zhǔn)備洗衣服(1) + 舉50下杠鈴 (5)分鐘+ 關(guān)洗衣機(jī) 1分鐘 + 舉杠鈴20下 (2)分鐘+ 關(guān)燒水機(jī) 1分鐘 + 舉30下杠鈴(3)分鐘
1+1+5+1+2+1+3 =14 分鐘
雙核 異步 并行
核1 準(zhǔn)備燒開水 1分鐘+ 舉杠鈴50下(5)分鐘+ 等待3分鐘 + 關(guān)掉燒水機(jī) 1分鐘
核2 準(zhǔn)備洗衣服 1分鐘+ 舉杠鈴50下(5)分鐘+ 關(guān)掉洗衣機(jī) 1分鐘 + 等待3分鐘
其實(shí)只花了 1+5+3+1 = 10分鐘
其中還有雙核都等待了3分鐘
雙核 異步 非并行
核1 舉杠鈴100下(10)分鐘
核2 準(zhǔn)備燒開水 1分鐘+ 準(zhǔn)備洗衣服 1分鐘+ 等待5 分鐘+ + 關(guān)掉燒水機(jī) 1分鐘 + 等待 1 分鐘 + 關(guān)掉洗衣機(jī) 1分鐘
其實(shí)只花了 1+5+3+1 = 10分鐘
多線程的做法
單核下
線程1 準(zhǔn)備燒開水 1分鐘, 等開水燒開 8 分鐘 , 關(guān)掉燒水機(jī) 1分鐘
線程2 舉杠鈴100下 10分鐘
線程3 準(zhǔn)備洗衣服 1分鐘, 等開水燒開 5 分鐘 , 關(guān)掉洗衣機(jī) 1分鐘
cpu 可能這么切換 最理想的切換方式
線程1 準(zhǔn)備燒開水1 sleep 1 sleep 5 sleep 1 sleep 2 關(guān)開水 1分鐘 exit
線程2 sleep 1 sleep 1 舉杠鈴50 5分鐘 sleep 1 舉杠鈴20 2分鐘 sleep1 舉杠鈴30下 3分鐘
線程3 sleep 1 準(zhǔn)備洗衣服1 分鐘 sleep 5 關(guān)洗衣機(jī)1分鐘 exit
***使用了 14分鐘 和異步是一樣的。
但是實(shí)際上是不一樣的,因?yàn)榫€程不會按照我們設(shè)想的去跑, 如果線程2 舉杠鈴先跑,整個(gè)流程的速度就下來了。
異步和同步的區(qū)別, 在io等待的時(shí)候,同步不會切走,浪費(fèi)了時(shí)間。
如果都是獨(dú)占cpu 的業(yè)務(wù), 比如舉杠鈴的業(yè)務(wù), 在單核情況下 多線和單線 沒有區(qū)別。
多線程的好處,比較容易的實(shí)現(xiàn)了 異步切換的思想, 因?yàn)楫惒降某绦蚝茈y寫的。多線程本身程還是以同步完成,但是應(yīng)該說
比效率是比不上異步的。 而且多線很容易寫, 相對效率也高。
多核的好處,就是可以同時(shí)做事情, 這個(gè)和單核完全不一樣的。