操作系統(tǒng)
什么是進程?
進程就是正在執(zhí)行的程序,是操作系統(tǒng)資源分配的基本單位糜工。一般來說舒憾,進程包含指令骡苞,數(shù)據(jù)和PCB视搏。
孤兒進程和僵尸進程碉就?
孤兒進程就是說一個父進程退出回梧,而他的一個或多個子進程還在運行废岂,那么這些子進程將成為孤兒進程。孤兒進程將被init進程(進程ID為1的進程)所收養(yǎng)狱意,并由init進程對他們完成狀態(tài)收集工作湖苞。因為孤兒進程會被init進程收養(yǎng),所以孤兒進程不會對系統(tǒng)造成危害详囤。
僵尸進程就是一個子進程的進程描述符在進程退出時不會釋放财骨,只有當父進程通過wait()或waitpid()獲取了子進程信息后才會釋放。如果子進程退出藏姐,而父進程并沒有調用wait()或waitpid()隆箩,那么子進程的進程描述符仍然保存在系統(tǒng)中,這種進程稱為僵尸進程羔杨。僵尸進程通過ps命令顯示的狀態(tài)為Z捌臊。
系統(tǒng)所能使用的進程號是有限的,如果產(chǎn)生大量僵尸進程兜材,可能會因為沒有可用的進程號而導致系統(tǒng)不能產(chǎn)生新的進程理澎。如果要消滅系統(tǒng)中大量的僵尸進程,只需要將其父進程殺死护姆,此時僵尸進程就會變成孤兒進程,從而被init進程所收養(yǎng)掏击,這樣init進程就會釋放所有的僵尸進程所占用的資源卵皂,從而結束僵尸進程。
什么是守護進程砚亭?
守護進程是運行在后臺的一種特殊進程灯变,他是獨立于控制終端的,并周期性地執(zhí)行某些任務捅膘。
什么是線程层扶?
線程是進程內部的不同的執(zhí)行路徑翻默,是操作系統(tǒng)獨立調度的基本單位。一個進程中可以有多個線程,他們共享進程資源镣屹。比如說极阅,微信和瀏覽器是兩個進程,瀏覽器進程里面有很多線程,例如http請求線程亚侠,事件響應線程,渲染線程等等俗扇,線程并發(fā)執(zhí)行使得在瀏覽器中點擊一個新連接從而發(fā)起http請求時硝烂,瀏覽器還可以響應用戶的其他事件。
進程和線程有什么區(qū)別铜幽?
擁有資源
進程是資源分配的基本單位滞谢,但是線程不擁有資源,線程可以訪問隸屬于進程的資源除抛。
調度
線程是獨立調度的基本單位狮杨,在同一進程中,線程的切換不會引起進程的切換镶殷,從一個進程中的線程切換到另一個進程中的線程時禾酱,會引起進程切換。
系統(tǒng)開銷
由于創(chuàng)建或撤銷進程時绘趋,系統(tǒng)都要為之分配或回收資源颤陶,如內存空間、I/O 設備等陷遮,所付出的開銷遠大于創(chuàng)建或撤銷線程時的開銷滓走。類似地,在進行進程切換時帽馋,涉及當前執(zhí)行進程 CPU 環(huán)境的保存及新調度進程 CPU 環(huán)境的設置搅方,而線程切換時只需保存和設置少量寄存器內容,開銷很小绽族。
通信方面
線程間可以通過直接讀寫同一進程中的數(shù)據(jù)進行通信姨涡,但是進程通信需要借助 IPC。
延伸問題:線程有哪兩種吧慢?
- 用戶級線程(user level thread):對于這類線程涛漂,有關線程管理的所有工作都由應用程序完成,內核意識不到線程的存在检诗。在應用程序啟動后匈仗,操作系統(tǒng)分配給該程序一個進程號,以及其對應的內存空間等資源逢慌。應用程序通常先在一個線程中運行悠轩,該線程被成為主線程。在其運行的某個時刻攻泼,可以通過調用線程庫中的函數(shù)創(chuàng)建一個在相同進程中運行的新線程火架。用戶級線程的好處是非常高效鉴象,不需要進入內核空間,但并發(fā)效率不高距潘。
- 內核級線程(kernel level thread):對于這類線程炼列,有關線程管理的所有工作由內核完成,應用程序沒有進行線程管理的代碼音比,只能調用內核線程的接口俭尖。內核維護進程及其內部的每個線程,調度也由內核基于線程架構完成洞翩。內核級線程的好處是稽犁,內核可以將不同線程更好地分配到不同的CPU,以實現(xiàn)真正的并行計算骚亿。
- 事實上已亥,在現(xiàn)代操作系統(tǒng)中,往往使用組合方式實現(xiàn)多線程来屠,即線程創(chuàng)建完全在用戶空間中完成虑椎,并且一個應用程序中的多個用戶級線程被映射到一些內核級線程上,相當于是一種折中方案俱笛。
并發(fā)和并行有什么區(qū)別捆姜?
并發(fā)就是在一段時間內,多個任務都會被處理迎膜;但在某一時刻泥技,只有一個任務在執(zhí)行。單核處理器可以做到并發(fā)磕仅。比如有兩個進程A和B珊豹,A運行一個時間片之后,切換到B榕订,B運行一個時間片之后又切換到A店茶。因為切換速度足夠快,所以宏觀上表現(xiàn)為在一段時間內能同時運行多個程序劫恒。
并行就是在同一時刻贩幻,有多個任務在執(zhí)行。這個需要多核處理器才能完成兼贸,在微觀上就能同時執(zhí)行多條指令段直,不同的程序被放到不同的處理器上運行吃溅,這個是物理上的多個進程同時進行溶诞。
大內核和微內核有什么區(qū)別?
- 大內核决侈,就是將操作系統(tǒng)的全部功能都放進內核里面螺垢,包括調度喧务、文件系統(tǒng)、網(wǎng)絡枉圃、設備驅動器功茴、存儲管理等等,組成一個緊密連接整體孽亲。大內核的優(yōu)點就是效率高坎穿,但是很難定位bug,拓展性比較差返劲,每次需要增加新的功能玲昧,都要將新的代碼和原來的內核代碼重新編譯。
- 微內核與單體內核不同篮绿,微內核只是將操作中最核心的功能加入內核孵延,包括IPC、地址空間分配和基本的調度亲配,這些東西都在內核態(tài)運行尘应,其他功能作為模塊被內核調用,并且是在用戶空間運行吼虎。微內核比較好維護和拓展犬钢,但是效率可能不高,因為需要頻繁地在內核態(tài)和用戶態(tài)之間切換鲸睛。
分時系統(tǒng)和實時系統(tǒng)有什么區(qū)別娜饵?
分時系統(tǒng)(Sharing time system)就是系統(tǒng)把CPU時間分成很短的時間片,輪流地分配給多個作業(yè)官辈。它的優(yōu)點就是對多個用戶的多個作業(yè)都能保證足夠快的響應時間箱舞,并且有效提高了資源的利用率。
實時系統(tǒng)(Real-time system)是系統(tǒng)對外部輸入的信息拳亿,能夠在規(guī)定的時間內(截止期限)處理完畢并做出反應晴股。它的優(yōu)點是能夠集中地及時地處理并作出反應,高可靠性肺魁,安全性电湘。
通常計算機采用的是分時,就是多個進程/用戶之間共享CPU鹅经,從形勢上實現(xiàn)多任務寂呛。各個用戶/進程之間的調度并非精準度特別高,如果一個進程被鎖住瘾晃,可以給它分配更多的時間贷痪。而實時操作系統(tǒng)則不同,軟件和硬件必須遵從嚴格的時間限制蹦误,超過時限的進程可能直接被終止劫拢。在這樣的操作系統(tǒng)中肉津,每次加鎖都需要仔細考慮。
靜態(tài)鏈接和動態(tài)鏈接有什么區(qū)別舱沧?
靜態(tài)鏈接就是在編譯期間妹沙,由編譯器和連接器將靜態(tài)庫集成到應用程序內,并制作成目標文件以及可以獨立運作的可執(zhí)行文件熟吏。靜態(tài)庫一般是一些外部函數(shù)與變量的集合距糖。
靜態(tài)庫很方便,但是如果我們只是想用庫中的某一個函數(shù)牵寺,卻仍然得把所有的內容都鏈接進去肾筐。一個更現(xiàn)代的方法是使用共享庫,避免了在文件中靜態(tài)庫的大量重復缸剪。
動態(tài)鏈接可以在首次載入的時候執(zhí)行吗铐,也可以在程序開始執(zhí)行的時候完成。這個是由動態(tài)鏈接器完成杏节,比方標準 C 庫(libc.so) 通常就是動態(tài)鏈接的唬渗,這樣所有的程序可以共享同一個庫,而不用分別進行封裝奋渔。
編譯有哪些階段镊逝?
- 預處理階段:處理以 # 開頭的預處理命令;
- 編譯階段:翻譯成匯編文件嫉鲸;
- 匯編階段:將匯編文件翻譯成可重定位目標文件撑蒜;
- 鏈接階段:將可重定位目標文件和 printf.o 等單獨預編譯好的目標文件進行合并,得到最終的- 可執(zhí)行目標文件玄渗。
進程有哪些狀態(tài)座菠?
在五狀態(tài)模型里面,進程一共有5中狀態(tài)藤树,分別是創(chuàng)建浴滴、就緒、運行岁钓、終止升略、阻塞。
- 運行狀態(tài)就是進程正在CPU上運行屡限。在單處理機環(huán)境下品嚣,每一時刻最多只有一個進程處于運行狀態(tài)。
- 就緒狀態(tài)就是說進程已處于準備運行的狀態(tài)钧大,即進程獲得了除CPU之外的一切所需資源翰撑,一旦得到CPU即可運行。
- 阻塞狀態(tài)就是進程正在等待某一事件而暫停運行拓型,比如等待某資源為可用或等待I/O完成额嘿。即使CPU空閑,該進程也不能運行劣挫。
- 運行態(tài)→阻塞態(tài):往往是由于等待外設册养,等待主存等資源分配或等待人工干預而引起的。
- 阻塞態(tài)→就緒態(tài):則是等待的條件已滿足压固,只需分配到處理器后就能運行球拦。
- 運行態(tài)→就緒態(tài):不是由于自身原因,而是由外界原因使運行狀態(tài)的進程讓出處理器帐我,這時候就變成就緒態(tài)坎炼。例如時間片用完,或有更高優(yōu)先級的進程來搶占處理器等拦键。
- 就緒態(tài)→運行態(tài):系統(tǒng)按某種策略選中就緒隊列中的一個進程占用處理器谣光,此時就變成了運行態(tài)。
進程調度算法有哪些芬为?
先來先服務
非搶占式的調度算法萄金,按照請求的順序進行調度。
有利于長作業(yè)媚朦,但不利于短作業(yè)氧敢,因為短作業(yè)必須一直等待前面的長作業(yè)執(zhí)行完畢才能執(zhí)行,而長作業(yè)又需要執(zhí)行很長時間询张,造成了短作業(yè)等待時間過長孙乖。另外,對I/O密集型進程也不利份氧,因為這種進程每次進行I/O操作之后又得重新排隊唯袄。
短作業(yè)優(yōu)先
非搶占式的調度算法,按估計運行時間最短的順序進行調度蜗帜。
長作業(yè)有可能會餓死越妈,處于一直等待短作業(yè)執(zhí)行完畢的狀態(tài)。因為如果一直有短作業(yè)到來钮糖,那么長作業(yè)永遠得不到調度梅掠。
最短剩余時間優(yōu)先
最短作業(yè)優(yōu)先的搶占式版本,按剩余運行時間的順序進行調度店归。 當一個新的作業(yè)到達時阎抒,其整個運行時間與當前進程的剩余時間作比較。如果新的進程需要的時間更少消痛,則掛起當前進程且叁,運行新的進程。否則新的進程等待秩伞。
時間片輪轉
將所有就緒進程按 FCFS 的原則排成一個隊列逞带,每次調度時欺矫,把 CPU 時間分配給隊首進程,該進程可以執(zhí)行一個時間片展氓。當時間片用完時穆趴,由計時器發(fā)出時鐘中斷,調度程序便停止該進程的執(zhí)行遇汞,并將它送往就緒隊列的末尾未妹,同時繼續(xù)把 CPU 時間分配給隊首的進程。
時間片輪轉算法的效率和時間片的大小有很大關系:
因為進程切換都要保存進程的信息并且載入新進程的信息空入,如果時間片太小络它,會導致進程切換得太頻繁,在進程切換上就會花過多時間歪赢。
而如果時間片過長化戳,那么實時性就不能得到保證。
優(yōu)先級調度
為每個進程分配一個優(yōu)先級埋凯,按優(yōu)先級進行調度迂烁。
為了防止低優(yōu)先級的進程永遠等不到調度,可以隨著時間的推移增加等待進程的優(yōu)先級递鹉。
延伸問題:什么是搶占式調度盟步?什么是非搶占式調度?
搶占式就是說操作系統(tǒng)將正在運行的進程強行暫停躏结,由調度器將CPU分配給其他就緒進程却盘。
非搶占式是調度器一旦把處理機分配給某進程后便讓它一直運行下去,直到進程完成或發(fā)生進程調度進程調度某事件而阻塞時媳拴,才把處理機分配給另一個進程黄橘。
什么是上下文切換?
對于單核單線程CPU而言屈溉,在某一時刻只能執(zhí)行一條CPU指令塞关。上下文切換(Context Switch)是一種將CPU資源從一個進程分配給另一個進程的機制。從用戶角度看子巾,計算機能夠并行運行多個進程帆赢,這恰恰是操作系統(tǒng)通過快速上下文切換造成的結果。在切換的過程中线梗,操作系統(tǒng)需要先存儲當前進程的狀態(tài)(包括內存空間的指針椰于,當前執(zhí)行完的指令等等),再讀入下一個進程的狀態(tài)仪搔,然后執(zhí)行此進程瘾婿。
系統(tǒng)調用和庫函數(shù)有什么區(qū)別?
- 系統(tǒng)調用是應用程序向系統(tǒng)內核請求服務的方式∑悖可以包括硬件相關的服務(例如抢呆,訪問硬盤等),或者創(chuàng)建新進程笛谦,調度其他進程等抱虐。系統(tǒng)調用是程序和操作系統(tǒng)之間的重要接口。
庫函數(shù)就是說把一些常用的函數(shù)編寫完放到一個文件里揪罕,編寫應用程序時調用,這是由第三方提供的宝泵,發(fā)生在用戶地址空間好啰。 - 在移植性方面,不同操作系統(tǒng)的系統(tǒng)調用一般是不同的儿奶,移植性差框往;庫函數(shù)會相對好一些。比如說在所有的ANSI C編譯器版本中闯捎,C庫函數(shù)是相同的椰弊。
- 在調用開銷方面,系統(tǒng)調用需要在用戶空間和內核環(huán)境間切換瓤鼻,開銷較大秉版;而庫函數(shù)調用開銷較小。
什么是死鎖茬祷?
在兩個或多個并發(fā)進程中清焕,如果一個進程集合中的每個進程都在等待只能由該進程集合中的其他進程才能引發(fā)的事件,那么該進程集合就產(chǎn)生了死鎖祭犯。
延伸問題:死鎖產(chǎn)生有哪些條件秸妥?
死鎖產(chǎn)生的根本原因是多個進程競爭資源時,進程的推進順序出現(xiàn)不正確沃粗。
- 互斥:每個資源要么已經(jīng)分配給了一個進程粥惧,要么就是可用的。
- 占有和等待:已經(jīng)得到了某個資源的進程可以再請求新的資源最盅。
- 不可搶占:已經(jīng)分配給一個進程的資源不能強制性地被搶占突雪,它只能被占有它的進程顯式地釋放。
- 環(huán)路等待:有兩個或者兩個以上的進程組成一條環(huán)路涡贱,該環(huán)路中的每個進程都在等待下一個進程所占有的資源挂签。
延伸問題:怎么解決死鎖?
對于死鎖盼产,主要有4種解決策略饵婆。
鴕鳥策略
就是直接忽略死鎖。就像鴕鳥遇到危險的時候,把頭埋在沙子里侨核,假裝根本沒發(fā)生問題草穆。因為解決死鎖問題的代價很高,因此鴕鳥策略這種不采取任務措施的方案會獲得更高的性能搓译。當發(fā)生死鎖時不會對用戶造成多大影響悲柱,或發(fā)生死鎖的概率很低,可以采用鴕鳥策略些己。大多數(shù)操作系統(tǒng)豌鸡,包括 Unix,Linux 和 Windows段标,處理死鎖問題的辦法僅僅是忽略它涯冠。
死鎖預防
死鎖預防是指通過破壞死鎖產(chǎn)生的四個必要條件中的一個或多個,以避免發(fā)生死鎖逼庞。
破壞互斥:不讓資源被一個進程獨占蛇更,可通過假脫機技術允許多個進程同時訪問資源;
破壞占有和等待:有兩種方案赛糟,
已擁有資源的進程不能再去請求其他資源派任。一種實現(xiàn)方法是要求進程在開始執(zhí)行前請求需要的所有資源。
要求進程請求資源時璧南,先暫時釋放其當前擁有的所有資源掌逛,再嘗試一次獲取所需的全部資源。破壞不可搶占:有些資源可以通過虛擬化方式實現(xiàn)可搶占司倚;
破壞循環(huán)等待:有兩種方案:
一種方法是保證每個進程在任何時刻只能占用一個資源颤诀,如果要請求另一個資源,必須先釋放第一個資源对湃;
另一種方法是將所有資源進行統(tǒng)一編號崖叫,進程可以在任何時刻請求資源,但要求進程必須按照順序請求資源拍柒。
死鎖避免
為了避免因為預防死鎖而導致所有線程變慢心傀,死鎖避免采用了與死鎖預防相反的措施。它允許三個必要條件拆讯,但通過算法判斷資源請求是否可能導致循環(huán)等待的形成并相應決策脂男,來避免死鎖點的產(chǎn)生。因此种呐,其前提是知道當前資源使用的整體情況宰翅,以及申請資源線程本身所占有的資源細節(jié)。
判斷和決策中爽室,主要使用兩種避免方法汁讼。
- 線程啟動拒絕:如果一個線程的請求會引發(fā)死鎖,則不允許其啟動。
- 資源分配拒絕:如果一個線程增加的資源請求會導致死鎖嘿架,則不允許此申請瓶珊。
整體來看,死鎖避免是從資源和線程相互間關系著手耸彪,避免形成循環(huán)等待是其主要任務伞芹。
死鎖檢測和恢復
可以允許系統(tǒng)進入死鎖狀態(tài),但會維護一個系統(tǒng)的資源分配圖蝉娜,定期調用死鎖檢測算法來檢測途中是否存在死鎖唱较,檢測到死鎖發(fā)生后,采取死鎖恢復算法進行恢復召川。
死鎖檢測方法如下:
- 在資源分配圖中南缓,找到不會阻塞又不獨立的進程結點,使該進程獲得其所需資源并運行扮宠,運行完畢后西乖,再釋放其所占有的全部資源狐榔。也就是消去該進程結點的請求邊和分配邊坛增。
- 使用上面的算法進行一系列簡化,若能消去所有邊薄腻,則表示不會出現(xiàn)死鎖收捣,否則會出現(xiàn)死鎖。
檢測到死鎖后庵楷,就需要解決死鎖罢艾。目前操作系統(tǒng)中主要采用如下幾種方法:
- 取消所有死鎖相關線程,簡單粗暴尽纽,但也確實是最常用的
- 把每個死鎖線程回滾到某些檢查點咐蚯,然后重啟
- 連續(xù)取消死鎖線程直到死鎖解除,順序基于特定最小代價原則
- 連續(xù)搶占資源直到死鎖解除
進程同步的方式有哪些弄贿?
臨界區(qū)
臨界區(qū)是一段代碼春锋,在臨界區(qū)內進程將訪問臨界資源。任何時候最多只有一個進程可以進入臨界區(qū)差凹,也就是說期奔,臨界區(qū)具有排他性。所以危尿,為了互斥訪問臨界資源呐萌,每個進程在進入臨界區(qū)之前,需要先進行檢查谊娇。
互斥量
就是使用一個互斥的變量來直接制約多個進程肺孤,每個進程只有擁有這個變量才具有訪問公共資源的權限,因為互斥量只有一個,所以能保證資源的正確訪問渠旁。
信號量
信號量(Semaphore)是一個整型變量攀例,可以對其執(zhí)行自增和自減操作,自減操作通常也叫做P操作顾腊,自增操作也稱為V操作粤铭。這兩個操作需要被設計成原語,是不可分割杂靶,通常的做法是在執(zhí)行這些操作的時候屏蔽中斷梆惯。進程使用這兩個操作進行同步。
- 對于P操作吗垮,如果執(zhí)行操作后信號量小于 0垛吗,那么執(zhí)行該操作的進程就會阻塞,否則繼續(xù)執(zhí)行烁登;
- 對于V操作怯屉,如果操作之后的信號量小于等于0,那么就會從阻塞隊列喚醒一個進程饵沧。
管程
管程使用的是面向對象思想锨络,將表示共享資源的數(shù)據(jù)結構還有相關的操作,包括同步機制狼牺,都集中并封裝到一起羡儿。所有進程都只能通過管程間接訪問臨界資源,而管程只允許一個進程進入并執(zhí)行操作是钥,從而實現(xiàn)進程互斥掠归。管程中設置了多個條件變量,表示多個進程被阻塞或掛起的條件悄泥。對條件變量執(zhí)行 wait() 操作會導致調用進程阻塞虏冻,把管程讓出來給另一個進程持有。signal() 操作用于喚醒被阻塞的進程弹囚。管程有一個重要特性厨相,就是在一個時刻只能有一個進程使用管程。進程在無法繼續(xù)執(zhí)行的時候不能一直占用管程余寥,否則其它進程永遠不能使用管程领铐。
進程間通信的方式有哪些?
管道
- 管道是半雙工的宋舷,數(shù)據(jù)只能向一個方向流動绪撵;如果需要雙方通信時,需要建立起兩個管道祝蝠。
- 管道只能用于父子進程或者兄弟進程之間或者說具有親緣關系的進程音诈;
- 管道對于管道兩端的進程而言幻碱,就是一個文件,但它不是普通的文件细溅,它不屬于某種文件系統(tǒng)褥傍,只存在與內存中。
- 管道的實質是一個內核緩沖區(qū)喇聊,進程以先進先出的方式從緩沖區(qū)存取數(shù)據(jù)恍风,管道一端的進程順序的將數(shù)據(jù)寫入緩沖區(qū),另一端的進程則順序的讀出數(shù)據(jù)誓篱。該緩沖區(qū)可以看做是一個循環(huán)隊列朋贬,讀和寫的位置都是自動增長的,不能隨意改變窜骄,一個數(shù)據(jù)只能被讀一次锦募,讀出來以后在緩沖區(qū)就不復存在了。當緩沖區(qū)讀空或者寫滿時邻遏,有一定的規(guī)則控制相應的讀進程或者寫進程進入等待隊列糠亩,當空的緩沖區(qū)有新數(shù)據(jù)寫入或者滿的緩沖區(qū)有數(shù)據(jù)讀出來時,就喚醒等待隊列中的進程繼續(xù)讀寫准验。
- 管道的主要局限性正體現(xiàn)在它的特點上赎线,比如只支持單向數(shù)據(jù)流,只能用于具有親緣關系的進程之間沟娱,沒有名字氛驮,管道的緩沖區(qū)是有限的等等腕柜。
命名管道
這種管道也叫FIFO济似。命名管道不同于管道的地方,在于它提供了一個路徑名與之關聯(lián)盏缤,以命名管道的文件形式存在于文件系統(tǒng)中砰蠢,這樣,即使與命名管道的創(chuàng)建進程不存在親緣關系的進程唉铜,只要可以訪問文件系統(tǒng)中的這個路徑台舱,就能夠彼此通過命名管道相互通信。命名管道嚴格遵循先進先出原則的潭流,不支持諸如數(shù)據(jù)隨機定位竞惋。命名管道的名字存在于文件系統(tǒng)中,但內容存放在內存中灰嫉。
消息隊列
消息隊列是消息的鏈表拆宛,具有特定的格式,它是存放在內存里面的讼撒,并且每個消息隊列都有唯一的標識浑厚。消息隊列允許一個或多個進程向它寫入與讀取消息股耽,所以,利用消息隊列钳幅,一個進程可以將一個數(shù)據(jù)塊發(fā)送到另一個進程物蝙,每個數(shù)據(jù)塊都有一個類型哥蔚,接收進程可以獨立地接收含有不同類型的數(shù)據(jù)結構杭隙,這個過程是異步的,我們可以通過發(fā)送消息來避免命名管道的同步和阻塞問題谁不。但消息隊列的數(shù)據(jù)塊有一個最大長度的大小限制钠导。
共享內存
- 共享內存是針對其他通信機制運行效率較低而設計的丽惭,它可以讓多個進程可以可以直接讀寫同一塊內存空間,是最快的IPC形式辈双。
- 為了在多個進程間交換信息责掏,內核專門留出了一塊內存區(qū),可以由需要訪問的進程將其映射到自己的私有地址空間湃望。進程就可以直接讀寫這一塊內存而不需要進行數(shù)據(jù)的拷貝换衬,從而大大提高效率。
- 由于多個進程共享一段內存证芭,因此需要依靠某種同步機制來達到進程間的同步和互斥瞳浦。
信號量
信號量是一個計數(shù)器,可以用來控制多個進程對共享資源的訪問废士。它是一種類似于鎖的機制叫潦,就是防止某進程正在訪問共享資源時,其他進程也訪問該資源官硝。
Socket
Socket就是套接字矗蕊,套接字也是一種通信機制,憑借這種機制氢架,可以讓不在同一臺主機上的兩個進程傻咖,通過網(wǎng)絡進行通信,一般可以用在客戶端和服務器之間的通信岖研。
實際上卿操,Socket 是在應用層和傳輸層之間的一個抽象層,它把 TCP/IP 協(xié)議的傳輸層里面復雜的操作孙援,抽象為幾個簡單的接口害淤,供應用層調用實現(xiàn)進程在網(wǎng)絡中的通信。
延伸問題:Socket通信流程是怎樣的拓售?
- 概括地說窥摄,就是通信的兩端都建立了一個 Socket ,然后通過 Socket 對數(shù)據(jù)進行傳輸邻辉。通常服務器處于一個無限循環(huán)溪王,等待客戶端的連接腮鞍。
- 對于客戶端,它的的過程比較簡單莹菱,首先創(chuàng)建 Socket移国,通過TCP連接服務器,將 Socket 與遠程主機的某個進程連接道伟,然后就發(fā)送數(shù)據(jù)迹缀,或者讀取響應數(shù)據(jù),直到數(shù)據(jù)交換完畢蜜徽,關閉連接祝懂,結束 TCP 對話。
- 對于服務端拘鞋,先初始化 Socket砚蓬,建立流式套接字,與本機地址及端口進行綁定盆色,然后通知 TCP灰蛙,準備好接收連接,調用 accept() 阻塞隔躲,等待來自客戶端的連接摩梧。如果這時客戶端與服務器建立了連接,客戶端發(fā)送數(shù)據(jù)請求宣旱,服務器接收請求并處理請求仅父,然后把響應數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù)浑吟,直到數(shù)據(jù)交換完畢笙纤。最后關閉連接,交互結束买置。
延伸問題:從TCP連接的角度說說Socket通信流程粪糙。
首先是三次握手的Socket交互流程强霎。
- 服務器調用 socket()忿项、bind()、listen() 完成初始化后城舞,調用 accept() 阻塞等待轩触;
- 客戶端 Socket 對象調用 connect() 向服務器發(fā)送了一個 SYN 并阻塞;
- 服務器完成了第一次握手家夺,即發(fā)送 SYN 和 ACK 應答脱柱;
- 客戶端收到服務端發(fā)送的應答之后,從 connect() 返回拉馋,再發(fā)送一個 ACK 給服務器榨为;
- 服務器 Socket 對象接收客戶端第三次握手 ACK 確認惨好,此時服務端從 accept() 返回,建立連接随闺。
接下來就是兩個端的連接對象互相收發(fā)數(shù)據(jù)日川。
然后是四次揮手的Socket交互流程。
- 某個應用進程調用 close() 主動關閉矩乐,發(fā)送一個 FIN龄句;
- 另一端接收到 FIN 后被動執(zhí)行關閉,并發(fā)送 ACK 確認散罕;
- 之后被動執(zhí)行關閉的應用進程調用 close() 關閉 Socket分歇,并也發(fā)送一個 FIN;
- 接收到這個 FIN 的一端向另一端 ACK 確認欧漱。
有哪些磁盤調度算法职抡?
先來先服務
- 按照磁盤請求的順序進行調度。
- 優(yōu)點是公平和簡單误甚。缺點也很明顯繁调,因為未對尋道做任何優(yōu)化,使平均尋道時間可能較長靶草。
最短尋道時間優(yōu)先
- 優(yōu)先調度與當前磁頭所在磁道距離最近的磁道蹄胰。
- 雖然平均尋道時間比較低,但是不夠公平奕翔。如果新到達的磁道請求總是比一個在等待的磁道請求近裕寨,那么在等待的磁道請求會一直等待下去,也就是出現(xiàn)饑餓現(xiàn)象派继。一般來說宾袜,兩端的磁道請求更容易出現(xiàn)饑餓現(xiàn)象。
電梯算法
也叫SCAN掃描算法驾窟。電梯算法就是說讀寫磁頭總是保持一個方向運行庆猫,直到該方向沒有請求為止,然后改變運行方向绅络。
因為考慮了移動方向月培,因此所有的磁盤請求都會被滿足,解決了最短尋道時間優(yōu)先的饑餓問題恩急。
什么是虛擬內存杉畜?
虛擬內存就是說,讓物理內存擴充成更大的邏輯內存衷恭,從而讓程序獲得更多的可用內存此叠。虛擬內存使用部分加載的技術,讓一個進程或者資源的某些頁面加載進內存随珠,從而能夠加載更多的進程灭袁,甚至能加載比內存大的進程猬错,這樣看起來好像內存變大了,這部分內存其實包含了磁盤或者硬盤茸歧,并且就叫做虛擬內存兔魂。
什么是分頁系統(tǒng)?
分頁就是說举娩,將磁盤或者硬盤分為大小固定的數(shù)據(jù)塊析校,叫做頁,然后內存也分為同樣大小的塊铜涉,叫做頁框智玻。當進程執(zhí)行的時候,會將磁盤的頁載入內存的某些頁框中芙代,并且正在執(zhí)行的進程如果發(fā)生缺頁中斷也會發(fā)生這個過程吊奢。頁和頁框都是由兩個部分組成的,一個是頁號或者頁框號纹烹,一個是偏移量页滚。分頁一般是有硬件來完成的,每個頁都對應一個頁框铺呵,它們的對應關系存放在一個叫做頁表的數(shù)據(jù)結構中裹驰,頁號作為這個頁表的索引,頁框號作為頁表的值片挂。操作系統(tǒng)負責維護這個頁表幻林。
分頁和分段有什區(qū)別?
- 分頁對程序員是透明的音念,但是分段需要程序員顯式劃分每個段沪饺。
- 分頁的地址空間是一維地址空間,分段是二維的闷愤。
- 頁的大小不可變整葡,段的大小可以動態(tài)改變。
- 分頁主要用于實現(xiàn)虛擬內存讥脐,從而獲得更大的地址空間遭居;分段主要是為了使程序和數(shù)據(jù)可以被劃分為邏輯上獨立的地址空間并且有助于共享和保護。
頁面替換算法有哪些攘烛?
在程序運行過程中魏滚,如果要訪問的頁面不在內存中,就發(fā)生缺頁中斷從而將該頁調入內存中坟漱。此時如果內存已無空閑空間,系統(tǒng)必須從內存中調出一個頁面到磁盤對換區(qū)中來騰出空間更哄。
最佳算法
所選擇的被換出的頁面將是最長時間內不再被訪問芋齿,通承瓤埽可以保證獲得最低的缺頁率。這是一種理論上的算法觅捆,因為無法知道一個頁面多長時間不再被訪問赦役。
先進先出
選擇換出的頁面是最先進入的頁面。該算***將那些經(jīng)常被訪問的頁面也被換出栅炒,從而使缺頁率升高掂摔。
LRU
雖然無法知道將來要使用的頁面情況,但是可以知道過去使用頁面的情況赢赊。LRU 將最近最久未使用的頁面換出乙漓。為了實現(xiàn) LRU,需要在內存中維護一個所有頁面的鏈表释移。當一個頁面被訪問時叭披,將這個頁面移到鏈表表頭。這樣就能保證鏈表表尾的頁面是最近最久未訪問的玩讳。因為每次訪問都需要更新鏈表涩蜘,因此這種方式實現(xiàn)的 LRU 代價很高。
時鐘算法
時鐘算法使用環(huán)形鏈表將頁面連接起來熏纯,再使用一個指針指向最老的頁面同诫。它將整個環(huán)形鏈表的每一個頁面做一個標記,如果標記是0樟澜,那么暫時就不會被替換剩辟,然后時鐘算法遍歷整個環(huán),遇到標記為1的就替換往扔,否則將標記為0的標記為1贩猎。
Linux文件系統(tǒng)是怎么樣的?
Linux文件系統(tǒng)里面有文件和目錄萍膛,組成一個樹狀的結構吭服,樹的每一個葉子節(jié)點表示文件或者空目錄。每個文件基本上都由兩部分組成:
- inode:一個文件占用一個 inode蝗罗,記錄文件的屬性艇棕,同時記錄此文件的內容所在的 block 編號;
- block:記錄文件的內容串塑,文件太大時沼琉,會占用多個 block。
除此之外還包括: - superblock:記錄文件系統(tǒng)的整體信息桩匪,包括 inode 和 block 的總量打瘪、使用量、剩余量,以及文件系統(tǒng)的格式與相關信息等闺骚;
-
block bitmap:記錄 block 是否被使用的位圖彩扔。
當要讀取一個文件的內容時,先在 inode 中查找文件內容所在的所有 block僻爽,然后把所有 block 的內容讀出來虫碉。
在這里插入圖片描述
硬鏈接和軟鏈接有什么區(qū)別?
硬鏈接就是在目錄下創(chuàng)建一個條目胸梆,記錄著文件名與 inode 編號敦捧,這個 inode 就是源文件的 inode。刪除任意一個條目碰镜,文件還是存在兢卵,只要引用數(shù)量不為 0。但是硬鏈接有限制洋措,它不能跨越文件系統(tǒng)济蝉,也不能對目錄進行鏈接。
符號鏈接文件保存著源文件所在的絕對路徑菠发,在讀取時會定位到源文件上王滤,可以理解為 Windows 的快捷方式。當源文件被刪除了滓鸠,鏈接文件就打不開了雁乡。因為記錄的是路徑,所以可以為目錄建立符號鏈接糜俗。
文章也會持續(xù)更新踱稍,可以微信搜索「 邁莫coding 」第一時間閱讀。