計(jì)算機(jī)底層知識(shí)

姓名:王紫圣? ? 學(xué)號(hào):16130140355

轉(zhuǎn)載自: 手游實(shí)驗(yàn)室

【嵌牛導(dǎo)讀】本章主要介紹操作系統(tǒng)挑围、文件系統(tǒng)相關(guān)的知識(shí)要點(diǎn)。大部分互聯(lián)網(wǎng)公司的軟件開(kāi)發(fā)職位面試可能不會(huì)直接涉及這一層面的知識(shí)蛋哭,但并不意味著這部分知識(shí)不重要求厕。對(duì)于計(jì)算機(jī)底層實(shí)現(xiàn)的深入理解趣苏,能幫助你了解計(jì)算機(jī)的運(yùn)行原理,能夠更好地設(shè)計(jì)高效的架構(gòu)凿歼,并且有助于調(diào)試褪迟、判斷錯(cuò)誤。特別地答憔,對(duì)于多線程的理解尤為重要:現(xiàn)今的程序架構(gòu)都需要并發(fā)處理味赃,如何協(xié)調(diào)不同線程之間的分工協(xié)作,避免死鎖虐拓、同步出錯(cuò)等問(wèn)題心俗,是程序員應(yīng)當(dāng)具備的技能。對(duì)于后端工程師而言蓉驹,良好的操作系統(tǒng)知識(shí)基礎(chǔ)更是深刻理解并實(shí)現(xiàn)復(fù)雜分布式系統(tǒng)的前提條件城榛。

【嵌牛鼻子】系統(tǒng)底層

【嵌牛提問(wèn)】編代碼的你到底知不知道系統(tǒng)底層是什么

【嵌牛正文】進(jìn)程vs.線程

進(jìn)程(process)與線程(thread)最大的區(qū)別是:進(jìn)程擁有自己的地址空間,某進(jìn)程內(nèi)的線程對(duì)于其他進(jìn)程不可見(jiàn)态兴,即進(jìn)程A不能通過(guò)傳地址的方式直接讀寫進(jìn)程B的存儲(chǔ)區(qū)域狠持。進(jìn)程之間的通信需要通過(guò)進(jìn)程間通信(Inter-Process Communication,IPC)瞻润。與之相對(duì)的喘垂,同一進(jìn)程的各線程間之間可以直接通過(guò)傳遞地址或全局變量的方式傳遞信息甜刻。

此外,進(jìn)程作為操作系統(tǒng)中擁有資源和獨(dú)立調(diào)度的基本單位正勒,可以擁有多個(gè)線程得院。通常操作系統(tǒng)中運(yùn)行的一個(gè)程序就對(duì)應(yīng)一個(gè)進(jìn)程。在同一進(jìn)程中章贞,線程的切換不會(huì)引起進(jìn)程切換祥绞。在不同進(jìn)程中進(jìn)行線程切換,如從一個(gè)進(jìn)程內(nèi)的線程切換到另一個(gè)進(jìn)程中的線程時(shí)鸭限,會(huì)引起進(jìn)程切換蜕径。相比進(jìn)程切換,線程切換的開(kāi)銷要小很多里覆。線程于進(jìn)程相互結(jié)合能夠提高系統(tǒng)的運(yùn)行效率。

線程可以分為兩類:

一類是用戶級(jí)線程(user level thread)缆瓣。對(duì)于這類線程喧枷,有關(guān)線程管理的所有工作都由應(yīng)用程序完成,內(nèi)核意識(shí)不到線程的存在弓坞。在應(yīng)用程序啟動(dòng)后隧甚,操作系統(tǒng)分配給該程序一個(gè)進(jìn)程號(hào),以及其對(duì)應(yīng)的內(nèi)存空間等資源渡冻。應(yīng)用程序通常先在一個(gè)線程中運(yùn)行戚扳,該線程稱為主線程。在其運(yùn)行的某個(gè)時(shí)刻族吻,可以通過(guò)調(diào)用線程庫(kù)中的函數(shù)創(chuàng)建一個(gè)在相同進(jìn)程中運(yùn)行的新線程帽借。 用戶級(jí)線程的好處是非常高效,不需要進(jìn)入內(nèi)核空間超歌,但并發(fā)效率不高砍艾。

另一類是內(nèi)核級(jí)線程(kernel level thread)。對(duì)于這類線程巍举,有關(guān)線程管理的所有工作由內(nèi)核完成脆荷,應(yīng)用程序沒(méi)有進(jìn)行線程管理的代碼,只能調(diào)用內(nèi)核線程的接口懊悯。內(nèi)核維護(hù)進(jìn)程及其內(nèi)部的每個(gè)線程蜓谋,調(diào)度也由內(nèi)核基于線程架構(gòu)完成。內(nèi)核級(jí)線程的好處是炭分,內(nèi)核可以將不同線程更好地分配到不同的CPU桃焕,以實(shí)現(xiàn)真正的并行計(jì)算。

事實(shí)上捧毛,在現(xiàn)代操作系統(tǒng)中覆旭,往往使用組合方式實(shí)現(xiàn)多線程退子,即線程創(chuàng)建完全在用戶空間中完成,并且一個(gè)應(yīng)用程序中的多個(gè)用戶級(jí)線程被映射到一些內(nèi)核級(jí)線程上型将,相當(dāng)于是一種折中方案寂祥。

上下文切換

對(duì)于單核單線程CPU而言,在某一時(shí)刻只能執(zhí)行一條CPU指令七兜。上下文切換(Context Switch)是一種將CPU資源從一個(gè)進(jìn)程分配給另一個(gè)進(jìn)程的機(jī)制丸凭。從用戶角度看,計(jì)算機(jī)能夠并行運(yùn)行多個(gè)進(jìn)程腕铸,這恰恰是操作系統(tǒng)通過(guò)快速上下文切換造成的結(jié)果惜犀。在切換的過(guò)程中,操作系統(tǒng)需要先存儲(chǔ)當(dāng)前進(jìn)程的狀態(tài)(包括內(nèi)存空間的指針狠裹,當(dāng)前執(zhí)行完的指令等等)虽界,再讀入下一個(gè)進(jìn)程的狀態(tài),然后執(zhí)行此進(jìn)程涛菠。

系統(tǒng)調(diào)用

系統(tǒng)調(diào)用(System Call)是程序向系統(tǒng)內(nèi)核請(qǐng)求服務(wù)的方式莉御。可以包括硬件相關(guān)的服務(wù)(例如俗冻,訪問(wèn)硬盤等)礁叔,或者創(chuàng)建新進(jìn)程,調(diào)度其他進(jìn)程等迄薄。系統(tǒng)調(diào)用是程序和操作系統(tǒng)之間的重要接口琅关。

Semaphore/Mutex

當(dāng)用戶創(chuàng)立多個(gè)線程/進(jìn)程時(shí)党瓮,如果不同線程/進(jìn)程同時(shí)讀寫相同的內(nèi)容最岗,則可能造成讀寫錯(cuò)誤蕉陋,或者數(shù)據(jù)不一致李破。此時(shí)聚凹,需要通過(guò)加鎖的方式摩钙,控制核心區(qū)域(critical section)的訪問(wèn)權(quán)限臂外。對(duì)于semaphore而言伴澄,在初始化變量的時(shí)候可以控制允許多少個(gè)線程/進(jìn)程同時(shí)訪問(wèn)一個(gè)核心區(qū)域碰缔,其他的線程/進(jìn)程會(huì)被堵塞账劲,直到有人解鎖。Mutex相當(dāng)于只允許一個(gè)線程/進(jìn)程訪問(wèn)的semaphore金抡。此外瀑焦,根據(jù)實(shí)際需要,人們還實(shí)現(xiàn)了一種讀寫鎖(read-write lock)梗肝,它允許同時(shí)存在多個(gè)讀取者(reader)榛瓮,但任何時(shí)候至多只有一個(gè)寫入者(writer),且不能與讀取者共存巫击。

死鎖

在引入鎖的同時(shí)禀晓,我們遇到了一個(gè)新的問(wèn)題:死鎖(Deadlock)精续。死鎖是指兩個(gè)或多個(gè)線程/進(jìn)程之間相互阻塞,以至于任何一個(gè)都不能繼續(xù)運(yùn)行粹懒,因此也不能解鎖其他線程/進(jìn)程重付。例如,線程A占有l(wèi)ock A凫乖,并且嘗試獲取lock B确垫;而線程2占有l(wèi)ock B,嘗試獲取lock A帽芽。此時(shí)删掀,兩者相互阻塞,都無(wú)法繼續(xù)運(yùn)行导街。

產(chǎn)生死鎖的4個(gè)條件概括如下(只有當(dāng)4個(gè)條件同時(shí)滿足時(shí)才會(huì)產(chǎn)生死鎖):

(1)Mutual Exclusion – Only one process may use a resource at a time

(2)Hold-and-Wait – Process holds resource while waiting for another

(3)No Preemption – Can’t take a resource away from a process

(4)Circular Wait – The waiting processes form a cycle

生產(chǎn)者消費(fèi)者

生產(chǎn)者消費(fèi)者模型是一種常見(jiàn)的通信模型:生產(chǎn)者和消費(fèi)者共享一個(gè)數(shù)據(jù)管道披泪,生產(chǎn)者將數(shù)據(jù)寫入buffer,消費(fèi)者從另一頭讀取數(shù)據(jù)搬瑰。對(duì)于數(shù)據(jù)管道款票,需要考慮為空和溢出的情況。同時(shí)跌捆,通常還需要將這部分共享內(nèi)存用mutex加鎖徽职。在只有一個(gè)生產(chǎn)者一個(gè)消費(fèi)者的情況下象颖,可以設(shè)計(jì)無(wú)鎖隊(duì)列(lockless queue)佩厚,線程安全地直接讀寫數(shù)據(jù)。

進(jìn)程間通信

在介紹進(jìn)程的時(shí)候说订,我們提起過(guò)一個(gè)進(jìn)程不能直接讀寫另一個(gè)進(jìn)程的數(shù)據(jù)抄瓦,兩者之間的通信需要通過(guò)進(jìn)程間通信進(jìn)行。進(jìn)程通信的方式通常遵從生產(chǎn)者消費(fèi)者模型陶冷,需要實(shí)現(xiàn)數(shù)據(jù)交換和同步兩大功能钙姊。

(1)共享內(nèi)存(Shared-memory)+ semaphore

不同進(jìn)程通過(guò)讀寫操作系統(tǒng)中特殊的共享內(nèi)存進(jìn)行數(shù)據(jù)交換,進(jìn)程之間用semaphore實(shí)現(xiàn)同步埂伦。

(2)信息傳遞(Message passing)

進(jìn)程在操作系統(tǒng)內(nèi)部注冊(cè)一個(gè)端口煞额,并且監(jiān)測(cè)有沒(méi)有數(shù)據(jù),其他進(jìn)程直接寫數(shù)據(jù)到該端口沾谜。該通信方式更加接近于網(wǎng)絡(luò)通信方式膊毁。事實(shí)上,網(wǎng)絡(luò)通信也是一種IPC基跑,只是進(jìn)程分布在不同機(jī)器上而已婚温。

邏輯地址/物理地址/虛擬內(nèi)存

所謂的邏輯地址,是指計(jì)算機(jī)用戶(例如程序開(kāi)發(fā)者)看到的地址媳否。例如栅螟,當(dāng)創(chuàng)建一個(gè)長(zhǎng)度為100的整型數(shù)組時(shí)荆秦,操作系統(tǒng)返回一個(gè)邏輯上的連續(xù)空間:指針指向數(shù)組第一個(gè)元素的內(nèi)存地址。由于整型元素的大小為4個(gè)字節(jié)力图,故第二個(gè)元素的地址時(shí)起始地址加4步绸,以此類推。事實(shí)上搪哪,邏輯地址并不一定是元素存儲(chǔ)的真實(shí)地址靡努,即數(shù)組元素的物理地址(在內(nèi)存條中所處的位置),物理地址并不是連續(xù)的晓折,只不過(guò)操作系統(tǒng)通過(guò)地址映射惑朦,將邏輯地址映射成連續(xù)的,這樣更符合人們的直觀思維漓概。

另一個(gè)重要概念是虛擬內(nèi)存漾月。操作系統(tǒng)讀寫內(nèi)存的速度可以比讀寫磁盤的速度快幾個(gè)量級(jí)。但是胃珍,內(nèi)存價(jià)格也相對(duì)較高梁肿,不能大規(guī)模擴(kuò)展。于是觅彰,操作系統(tǒng)可以將部分不太常用的數(shù)據(jù)移出內(nèi)存吩蔑,存放到價(jià)格相對(duì)較低的磁盤緩存,以實(shí)現(xiàn)內(nèi)存擴(kuò)展填抬。操作系統(tǒng)還可以通過(guò)算法預(yù)測(cè)哪部分存儲(chǔ)到磁盤緩存的數(shù)據(jù)需要進(jìn)行讀寫烛芬,提前把這部分?jǐn)?shù)據(jù)讀回內(nèi)存。虛擬內(nèi)存空間相對(duì)磁盤而言要小很多飒责,因此赘娄,即使搜索虛擬內(nèi)存空間也比直接搜索磁盤要快。唯一慢于磁盤的可能是宏蛉,內(nèi)存遣臼、虛擬內(nèi)存中都沒(méi)有所需要的數(shù)據(jù),最終還需要從硬盤中直接讀取拾并。這就是為什么內(nèi)存和虛擬內(nèi)存中需要存儲(chǔ)會(huì)被重復(fù)讀寫的數(shù)據(jù)揍堰,否則就失去了緩存的意義。

現(xiàn)代計(jì)算機(jī)中有一個(gè)專門的轉(zhuǎn)譯緩沖區(qū)(Translation Lookaside Buffer嗅义,TLB)屏歹,用來(lái)實(shí)現(xiàn)虛擬地址到物理地址的快速轉(zhuǎn)換。

與內(nèi)存/虛擬內(nèi)存相關(guān)的還有以下兩個(gè)概念:

(1)Resident Set

當(dāng)一個(gè)進(jìn)程在運(yùn)行的時(shí)候芥喇,操作系統(tǒng)不會(huì)一次性加載進(jìn)程的所有數(shù)據(jù)到內(nèi)存西采,只會(huì)加載一部分正在用,以及預(yù)期要用的數(shù)據(jù)继控。其他數(shù)據(jù)可能存儲(chǔ)在虛擬內(nèi)存械馆,交換區(qū)和硬盤文件系統(tǒng)上胖眷。被加載到內(nèi)存的部分就是resident set。

(2)Thrashing

由于resident set包含預(yù)期要用的數(shù)據(jù)霹崎,理想情況下珊搀,進(jìn)程運(yùn)行過(guò)程中用到的數(shù)據(jù)都會(huì)逐步加載進(jìn)resident set。但事實(shí)往往并非如此:每當(dāng)需要的內(nèi)存頁(yè)面(page)不在resident set中時(shí)尾菇,操作系統(tǒng)必須從虛擬內(nèi)存或硬盤中讀數(shù)據(jù)境析,這個(gè)過(guò)程被稱為內(nèi)存頁(yè)面錯(cuò)誤(page faults)。當(dāng)操作系統(tǒng)需要花費(fèi)大量時(shí)間去處理頁(yè)面錯(cuò)誤的情況就是thrashing派诬。

文件系統(tǒng)

UNIX風(fēng)格的文件系統(tǒng)利用樹(shù)形結(jié)構(gòu)管理文件劳淆。每個(gè)節(jié)點(diǎn)有多個(gè)指針,指向下一層節(jié)點(diǎn)或者文件的磁盤存儲(chǔ)位置默赂。文件節(jié)點(diǎn)還附有文件的操作信息(metadata)沛鸵,包括修改時(shí)間、訪問(wèn)權(quán)限等缆八。

用戶的訪問(wèn)權(quán)限通過(guò)訪問(wèn)控制表(Access Control List)和能力表(Capability List)實(shí)現(xiàn)曲掰。前者從文件角度出發(fā),標(biāo)注了每個(gè)用戶可以對(duì)該文件進(jìn)行何種操作奈辰。后者從用戶角度出發(fā)栏妖,標(biāo)注了某用戶可以以什么權(quán)限操作哪些文件。

UNIX的文件權(quán)限分為讀奖恰、寫和執(zhí)行吊趾,用戶組分為文件擁有者、組和所有用戶房官≈夯眨可以通過(guò)命令對(duì)三組用戶分別設(shè)置權(quán)限续滋。

實(shí)時(shí)vs.分時(shí)操作系統(tǒng)

操作系統(tǒng)可以分為實(shí)時(shí)操作系統(tǒng)(Real-Time System)翰守,和分時(shí)操作系統(tǒng)(Sharing Time System)。通常計(jì)算機(jī)采用的是分時(shí)疲酌,即多個(gè)進(jìn)程/用戶之間共享CPU蜡峰,從形勢(shì)上實(shí)現(xiàn)多任務(wù)。各個(gè)用戶/進(jìn)程之間的調(diào)度并非精準(zhǔn)度特別高朗恳,如果一個(gè)進(jìn)程被鎖住湿颅,可以給它分配更多的時(shí)間。而實(shí)時(shí)操作系統(tǒng)則不同粥诫,軟件和硬件必須遵從嚴(yán)格的deadline油航,超過(guò)時(shí)限的進(jìn)程可能直接被終止。在這樣的操作系統(tǒng)中怀浆,每次加鎖都需要仔細(xì)考慮谊囚。

編譯器

對(duì)于高級(jí)語(yǔ)言來(lái)說(shuō)怕享,代碼需要通過(guò)編譯才能夠運(yùn)行。編譯通過(guò)編譯器(Compiler)實(shí)現(xiàn)镰踏,是一個(gè)將程序源代碼轉(zhuǎn)換成二進(jìn)制機(jī)器碼的過(guò)程函筋。計(jì)算機(jī)可以直接執(zhí)行二進(jìn)制代碼。在編譯的過(guò)程中奠伪,編譯器需要進(jìn)行詞法分析(Lexical Analysis)跌帐、解析(Parsing)和過(guò)渡代碼生成(Intermediate Code Generation)。編譯器的好壞可以直接影響最終代碼的執(zhí)行效率绊率。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谨敛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子滤否,更是在濱河造成了極大的恐慌佣盒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顽聂,死亡現(xiàn)場(chǎng)離奇詭異肥惭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)紊搪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門蜜葱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人耀石,你說(shuō)我怎么就攤上這事牵囤。” “怎么了滞伟?”我有些...
    開(kāi)封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵揭鳞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我梆奈,道長(zhǎng)野崇,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任亩钟,我火速辦了婚禮乓梨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘清酥。我一直安慰自己扶镀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布焰轻。 她就那樣靜靜地躺著臭觉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝠筑,一...
    開(kāi)封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天忆肾,我揣著相機(jī)與錄音,去河邊找鬼菱肖。 笑死客冈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的稳强。 我是一名探鬼主播场仲,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼退疫!你這毒婦竟也來(lái)了渠缕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤褒繁,失蹤者是張志新(化名)和其女友劉穎亦鳞,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體棒坏,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡燕差,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坝冕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片徒探。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖喂窟,靈堂內(nèi)的尸體忽然破棺而出测暗,到底是詐尸還是另有隱情,我是刑警寧澤磨澡,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布碗啄,位于F島的核電站,受9級(jí)特大地震影響稳摄,放射性物質(zhì)發(fā)生泄漏稚字。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一秩命、第九天 我趴在偏房一處隱蔽的房頂上張望尉共。 院中可真熱鬧褒傅,春花似錦弃锐、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春旋廷,著一層夾襖步出監(jiān)牢的瞬間鸠按,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工饶碘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留目尖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓扎运,卻偏偏與公主長(zhǎng)得像瑟曲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子豪治,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容