進程和線程的區(qū)別,什么是協(xié)程?
進程和線程的區(qū)別
線程與進程相似,但線程是一個比進程更小的執(zhí)行單位。一個進程在其執(zhí)行的過程中可以產(chǎn)生多個線程。與進程不同的是同類的多個線程共享同一塊內(nèi)存空間和一組系統(tǒng)資源,所以系統(tǒng)在產(chǎn)生一個線程,或是在各個線程之間作切換工作時,負(fù)擔(dān)要比進程小得多,也正因為如此,線程也被稱為輕量級進程。另外,也正是因為共享資源,所以線程中執(zhí)行時一般都要進行同步和互斥。總的來說,進程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。
- 進程是操作系統(tǒng)資源分配的基本單位,而線程是處理器任務(wù)調(diào)度和執(zhí)行的基本單位(根本區(qū)別)
- 線程是一個比進程更小的執(zhí)行單位。一個進程在其執(zhí)行的過程中可以產(chǎn)生多個線程,線程也被稱為輕量級進程(包含關(guān)系)
- 同一進程的線程共享本進程的地址空間和資源,而進程之間的地址空間和資源是相互獨立的。(內(nèi)存分配)
- 一個進程崩潰后,在保護模式下不會對其他進程產(chǎn)生影響,但是一個線程崩潰整個進程都死掉。所以多進程要比多線程健壯。(影響關(guān)系)
- 每個獨立的進程有程序運行的入口、順序執(zhí)行序列和程序出口。但是線程不能獨立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個線程執(zhí)行控制,兩者均可并發(fā)執(zhí)行。(執(zhí)行過程)
協(xié)程
協(xié)程(Coroutines)是一種比線程更加輕量級的存在,正如一個進程可以擁有多個線程一樣,一個線程可以擁有多個協(xié)程。
協(xié)程不是被操作系統(tǒng)內(nèi)核所管理的,而是完全由程序所控制,也就是在用戶態(tài)執(zhí)行。這樣帶來的好處是性能大幅度的提升,因為不會像線程切換那樣消耗資源。
協(xié)程不是進程也不是線程,而是一個特殊的函數(shù),這個函數(shù)可以在某個地方掛起,并且可以重新在掛起處外繼續(xù)運行。所以說,協(xié)程與進程、線程相比并不是一個維度的概念。
一個進程可以包含多個線程,一個線程也可以包含多個協(xié)程。簡單來說,一個線程內(nèi)可以由多個這樣的特殊函數(shù)在運行,但是有一點必須明確的是,一個線程的多個協(xié)程的運行是串行的。如果是多核CPU,多個進程或一個進程內(nèi)的多個線程是可以并行運行的,但是一個線程內(nèi)協(xié)程卻絕對是串行的,無論CPU有多少個核。畢竟協(xié)程雖然是一個特殊的函數(shù),但仍然是一個函數(shù)。一個線程內(nèi)可以運行多個函數(shù),但這些函數(shù)都是串行運行的。當(dāng)一個協(xié)程運行時,其它協(xié)程必須掛起。
協(xié)程的作用:
協(xié)程只有在非常有限制的情況下,才有一些用處,在單進程單線程任務(wù)中的交互之暇,才有它的用武之地。
協(xié)程算是用戶態(tài)的線程,優(yōu)勢主要是少了內(nèi)核態(tài)用戶態(tài)的切換和能自己來做調(diào)度。 然后協(xié)程一般只在有IO操作的時候才能用到,對于一些會阻塞的IO操作,可以自己選擇協(xié)程切換,等IO就緒了再切回來,可以更充分利用CPU。
進程和線程的切換者都是操作系統(tǒng),而協(xié)程的切換者是用戶,換時機是用戶自己的程序所決定的。
進程間通信方式IPC
-
共享內(nèi)存
共享內(nèi)存是最快的進程間通訊的方式
相對于其他幾種方式,共享內(nèi)存直接在進程的虛擬地址空間進行操作,不再通過執(zhí)行進入內(nèi)核的系統(tǒng)調(diào)用來傳遞彼此的數(shù)據(jù)
-
信號
信號量和以前的IPC通信方式不同,信號量的本質(zhì)是計數(shù)器,用于多進程對共享數(shù)據(jù)對象的訪問。
在進程訪問臨界資源之前,需要測試信號量,如果為正數(shù),則信號量-1并且進程可以進入臨界區(qū),若為非正數(shù),則進程掛起放入等待隊列,直至有進程退出臨界區(qū),釋放資源并+1信號量,此時喚醒等待隊列的進程。
信號量本身就是臨界資源,所以必須是原子操作。
-
管道
單向,一端輸入,另一端輸出,先進先出FIFO。管道也是文件。管道大小4096字節(jié)。
特點:管道滿時,寫阻塞;空時,讀阻塞。
分類:普通管道(僅父子進程間通信)位于內(nèi)存;命名管道位于文件系統(tǒng),沒有親緣關(guān)系管道只要知道管道名也可以通訊。
-
匿名管道與命名管道的區(qū)別:
匿名管道由pipe函數(shù)創(chuàng)建并打開。
命名管道由mkfifo函數(shù)創(chuàng)建,打開用open
FIFO(命名管道)與pipe(匿名管道)之間唯一的區(qū)別在它們創(chuàng)建與打開的方式不同,一但這些工作完成之后,它們具有相同的語義。
-
消息隊列
消息隊列是先進先出FIFO原則
-
信號量
是一個計數(shù)器,用來控制多個進程對資源的訪問,它通常作為一種鎖機制。
用戶態(tài)和核心態(tài)
概念
用戶態(tài):
當(dāng)一個進程在執(zhí)行用戶自己的代碼時處于用戶運行態(tài)(用戶態(tài)),此時特權(quán)級最低,為3級,是普通的用戶進程運行的特權(quán)級,大部分用戶直接面對的程序都是運行在用戶態(tài)。Ring3狀態(tài)不能訪問Ring0的地址空間,包括代碼和數(shù)據(jù);
內(nèi)核態(tài):
當(dāng)一個進程因為系統(tǒng)調(diào)用陷入內(nèi)核代碼中執(zhí)行時處于內(nèi)核運行態(tài)(內(nèi)核態(tài)),此時特權(quán)級最高,為0級。執(zhí)行的內(nèi)核代碼會使用當(dāng)前進程的內(nèi)核棧,每個進程都有自己的內(nèi)核棧。
區(qū)別
- 處于用戶態(tài)執(zhí)行時,進程所能訪問的內(nèi)存空間和對象受到限制,其所處于占有的處理機是可被搶占的
- 而處于核心態(tài)執(zhí)行中的進程,則能訪問所有的內(nèi)存空間和對象,且所占有的處理機是不允許被搶占的。
操作系統(tǒng)分配的進程空間是怎樣的?線程能共享哪些?
程序計數(shù)器,線程私有
虛擬機棧,線程私有
本地方法棧,線程私有
堆,線程公有
方法區(qū),線程公有
操作系統(tǒng)內(nèi)存管理方式,分頁分段以及段頁式的優(yōu)缺點
內(nèi)存管理方式
內(nèi)存管理方式主要分為:頁式管理、段式管理和段頁式管理。
分頁存儲管理:
頁表是系統(tǒng)為進程建立的數(shù)據(jù)結(jié)構(gòu),通過頁表實現(xiàn)從頁(邏輯地址)到頁框(物理地址)的映射。
分段存儲管理:
進程的地址空間被劃分成若干個段,系統(tǒng)為每個段分配一個連續(xù)的物理內(nèi)存區(qū)域,各個不同的段可以離散的放在物理內(nèi)存不同的區(qū)域。
段頁式存儲管理:
將用戶進程的邏輯空間先劃分為若干個段,每個段再劃分為若干個頁。進程以頁為單位在物理內(nèi)存中離散存放,每個段中被離散存放的頁具有邏輯相關(guān)性。
分頁分段以及段頁式的優(yōu)缺點
頁式:
優(yōu)點:沒有外碎片,每個內(nèi)碎片不超過頁的大小。
缺點:程序全部裝入內(nèi)存,要求有相應(yīng)的硬件支持,如地址變換機構(gòu)缺頁中斷的產(chǎn)生和選擇淘汰頁面等都要求有相應(yīng)的硬件支持。增加了機器成本和系統(tǒng)開銷。
段式:
優(yōu)點:可以分別編寫和編譯,可以針對不同類型的段采取不同的保護,可以按段為單位來進行共享,包括通過動態(tài)鏈接進行代碼共享。
缺點:會產(chǎn)生碎片。
段頁式:
優(yōu)點:段頁式管理是段式管理和頁式管理相結(jié)合而成,具有兩者的優(yōu)點。
缺點:由于管理軟件的增加,復(fù)雜性和開銷也增加。另外需要的硬件以及占用的內(nèi)存也有所增加,使得執(zhí)行速度下降。
頁面置換算法有哪些,F(xiàn)IFO為什么不好?如何改進?LRU思想,手寫LRU
-
最佳置換算法(OPT)(理想置換算法):從主存中移出永遠(yuǎn)不再需要的頁面;如無這樣的頁面存在,則選擇最長時間不需要訪問的頁面。于所選擇的被淘汰頁面將是以后永不使用的,或者是在最長時間內(nèi)不再被訪問的頁面,這樣可以保證獲得最低的缺頁率。 即被淘汰頁面是以后永不使用或最長時間內(nèi)不再訪問的頁面。(往后看)
訪問頁面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1 物理塊1 7 7 7 2 2 2 2 2 7 物理塊2 0 0 0 0 4 0 0 0 物理塊3 1 1 3 3 3 1 1 缺頁否 √ √ √ √ √ √ √ √ -
先進先出置換算法(FIFO):是最簡單的頁面置換算法。這種算法的基本思想是:當(dāng)需要淘汰一個頁面時,總是選擇駐留主存時間最長的頁面進行淘汰,即先進入主存的頁面先淘汰。其理由是:最早調(diào)入主存的頁面不再被使用的可能性最大。 即優(yōu)先淘汰最早進入內(nèi)存的頁面。(往前看)
訪問頁面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1 物理塊1 7 7 7 2 2 2 4 4 4 0 0 0 7 7 7 物理塊2 0 0 0 3 3 3 2 2 2 1 1 1 0 0 物理塊3 1 1 1 0 0 0 3 3 3 2 2 2 1 缺頁否 √ √ √ √ √ √ √ √ √ √ √ √ √ √ √ -
最近最久未使用(LRU)算法:這種算法的基本思想是:利用局部性原理,根據(jù)一個作業(yè)在執(zhí)行過程中過去的頁面訪問歷史來推測未來的行為。它認(rèn)為過去一段時間里不曾被訪問過的頁面,在最近的將來可能也不會再被訪問。所以,這種算法的實質(zhì)是:當(dāng)需要淘汰一個頁面時,總是選擇在最近一段時間內(nèi)最久不用的頁面予以淘汰。 即淘汰最近最長時間未訪問過的頁面。(往前看)
再對上面的實例釆用LRU算法進行頁面置換,如圖所示。進程第一次對頁面2訪問時,將最近最久未被訪問的頁面7置換出去。然后訪問頁面3時,將最近最久未使用的頁面1換出。
訪問頁面 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1 物理塊1 7 7 7 2 2 4 4 4 0 1 1 1 物理塊2 0 0 0 0 0 0 3 3 3 0 0 物理塊3 1 1 3 3 2 2 2 2 2 7 缺頁否 √ √ √ √ √ √ √ √ √ √ √ √ 實際上,LRU算法根據(jù)各頁以前的情況,是“向前看”的,而最佳置換算法則根據(jù)各頁以后的使用情況,是“向后看”的。
-
時鐘(CLOCK)置換算法
LRU算法的性能接近于OPT,但是實現(xiàn)起來比較困難,且開銷大;FIFO算法實現(xiàn)簡單,但性能差。所以操作系統(tǒng)的設(shè)計者嘗試了很多算法,試圖用比較小的開銷接近LRU的性能,這類算法都是CLOCK算法的變體。 簡單的CLOCK算法是給每一幀關(guān)聯(lián)一個附加位,稱為使用位。當(dāng)某一頁首次裝入主存時,該幀的使用位設(shè)置為1;當(dāng)該頁隨后再被訪問到時,它的使用位也被置為1。對于頁替換算法,用于替換的候選幀集合看做一個循環(huán)緩沖區(qū),并且有一個指針與之相關(guān)聯(lián)。當(dāng)某一頁被替換時,該指針被設(shè)置成指向緩沖區(qū)中的下一幀。當(dāng)需要替換一頁時,操作系統(tǒng)掃描緩沖區(qū),以查找使用位被置為0的一幀。每當(dāng)遇到一個使用位為1的幀時,操作系統(tǒng)就將該位重新置為0;如果在這個過程開始時,緩沖區(qū)中所有幀的使用位均為0,則選擇遇到的第一個幀替換;如果所有幀的使用位均為1,則指針在緩沖區(qū)中完整地循環(huán)一周,把所有使用位都置為0,并且停留在最初的位置上,替換該幀中的頁。由于該算法循環(huán)地檢查各頁面的情況,故稱為CLOCK算法,又稱為最近未用(Not Recently Used, NRU)算法。
FIFO為什么不好?如何改進?
FIFO原理:按照“先進先出(First In,F(xiàn)irst Out)”的原理淘汰數(shù)據(jù)
FIFO的實現(xiàn):
- 新訪問的數(shù)據(jù)插入FIFO隊列尾部,數(shù)據(jù)在FIFO隊列中順序移動;
- 淘汰FIFO隊列頭部的數(shù)據(jù);
特點:
>> 命中率 命中率很低,因為命中率太低,實際應(yīng)用中基本上不會采用。
>> 復(fù)雜度 簡單
>> 代價 實現(xiàn)代價很小

不好的原因:命中率很低,因為命中率太低,實際應(yīng)用中基本上不會采用。
改進: --> Second Chance
FIFO改進版,如果被淘汰的數(shù)據(jù)之前被訪問過,則給其第二次機會(Second Chance)
實現(xiàn):
每個數(shù)據(jù)會增加一個訪問標(biāo)志位,用于標(biāo)識此數(shù)據(jù)放入緩存隊列后是否被再次訪問過。
如上圖,A是FIFO隊列中最舊的數(shù)據(jù),且其放入隊列后沒有被再次訪問,則A被立刻淘汰;否則如果放入隊列后被訪問過,則將A移到FIFO隊列頭,并且將訪問標(biāo)志位清除。
如果所有的數(shù)據(jù)都被訪問過,則經(jīng)過一次循環(huán)后就會按照FIFO的原則淘汰數(shù)據(jù)。
特點:
>> 命中率 命中率比FIFO高。
>> 復(fù)雜度 與FIFO相比,需要記錄數(shù)據(jù)的訪問標(biāo)志位,且需要將數(shù)據(jù)移動
>> 代價 實現(xiàn)代價比FIFO高
死鎖條件,解決方式。
什么是死鎖?
死鎖是指兩個或兩個以上的進程在執(zhí)行過程中,由于競爭資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象,若無外力作用,它們都將無法推進下去。此時稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖。
死鎖條件
死鎖的四個必要條件:
- 互斥條件:對所分配到的資源不允許其他線程進行訪問,若其他線程訪問該資源,只能等待,直至占有該資源的線程使用完成后釋放該資源
- 請求和保持條件:線程程獲得一定的資源之后,又對其他資源發(fā)出請求,但是該資源可能被其他線程占有,此時請求阻塞,但又對自己獲得的資源保持不放
- 不可剝奪條件:線程已獲得的資源,在未完成使用之前,不可被剝奪,只能在使用完后自己釋放
- 環(huán)路等待條件:是指線程發(fā)生死鎖后,若干線程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系
如何防止死鎖
以上四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之 一不滿足,就不會發(fā)生死鎖。
所以,在系統(tǒng)設(shè)計、進程調(diào)度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配算法,避免進程永久占據(jù)系統(tǒng)資源。