欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:Linux:進(jìn)程地址空間

柚子快報邀請碼778899分享:Linux:進(jìn)程地址空間

http://yzkb.51969.com/

一、C語言內(nèi)存管理基礎(chǔ)

引入:以前我們知道一個指針指向的如果是一個常量字符串,那么這個就是指向的常量區(qū),只讀不可被修改,因此下面的程序會崩潰。

?1、在我們C語言內(nèi)存管理機(jī)制里面線性地址是有區(qū)域劃分的。

? ? ? ?我們?nèi)绾悟炞C這個區(qū)域的劃分是否正確呢?可以通過代碼的方式在不同的區(qū)域創(chuàng)建變量然后來取地址獲取再進(jìn)行比較

?2、棧區(qū)和堆區(qū)是相對而行的??!

?驗證棧區(qū):地址在變低

?驗證堆區(qū):地址在變高

3、靜態(tài)變量會被定義在全局區(qū)? 只不過只會在作用域里使用。

二、fork遺留問題

歷史遺留問題:為什么一個變量可以同時等于0又同時>0? ???

?實驗:

? ? ? ? 我們會發(fā)現(xiàn)同一個地址竟然讀到了不同的內(nèi)容?。?如果變量的地址是一個物理地址,是絕對不可能出現(xiàn)這種情況的,因此我們的變量地址必然是不是物理地址??!

——>結(jié)論:我們平時C/C++里面使用的地址全都不是物理地址,而是虛擬地址!?用戶是看不到物理地址的,而OS必須要負(fù)責(zé)將我們所看到的虛擬地址轉(zhuǎn)化成物理地址!

三、進(jìn)程地址空間

? ? ? ? 其實我們的之前所學(xué)的線性地址,并不是真正的物理內(nèi)存,而是在PCB內(nèi)部有一個指針指向了一塊進(jìn)程地址空間,然后虛擬地址會通過頁表來映射到具體的物理地址。 ——>所以當(dāng)我們創(chuàng)建出一個子進(jìn)程后,他會拷貝一份和父進(jìn)程一樣的地址空間,然后當(dāng)子進(jìn)程想要修改對應(yīng)的數(shù)據(jù)時,此時就會發(fā)生寫時拷貝(由操作系統(tǒng)自動完成),也就是重新開辟空間,在這個過程當(dāng)中只有頁表對應(yīng)的物理地址發(fā)生了變化,左邊的地址空間不會有任何的感知。

3.1 什么叫做地址空間?

? ? ? ?在32位的機(jī)器中,有32位的地址和數(shù)據(jù)總線,所以每一根地址總線有0或1,其實從本質(zhì)上來說計算機(jī)能夠識別是高低電頻而并非二進(jìn)制,所以1代表的是高電頻,0代表的是低電頻?!?這個過程就是CPU通過像內(nèi)存充電的形式告訴內(nèi)存我需要哪個地址,然后內(nèi)存就能夠通過識別高低電頻,形成一個物理數(shù)據(jù),將地址對應(yīng)的數(shù)據(jù)以同樣的方式交給CPU。

?所以地址空間就是地址總線排列組合形成的地址的范圍【0,2^32】?

3.2 如何理解地址空間的區(qū)域劃分?

?舉個例子:比方說當(dāng)前的桌子有100cm長,坐著小胖和小美,但是小胖經(jīng)常騷擾小美,所以就在桌子中間畫了一個三八線。 一人只有50cm的空間。所以從結(jié)構(gòu)上就可以如下劃分:

區(qū)域劃分就是通過結(jié)構(gòu)體內(nèi)部的start和end去做劃分?

?如何理解區(qū)域的變大或者變小呢??——>修改對應(yīng)結(jié)構(gòu)體內(nèi)部的start和end即可

我們不僅要看到地址空間的范圍,我們要知道在范圍內(nèi)連續(xù)的空間中,每一個最小單位都可以有地址,這個地址可以被直接使用!!?

3.3? 什么是進(jìn)程地址空間

? ? ? ?所謂進(jìn)程地址空間,本質(zhì)上就是一個描述進(jìn)程可視化范圍的地址空間內(nèi)存在各種區(qū)域劃分,對線性地址進(jìn)行start、end即可?。本質(zhì)上其實就是一個內(nèi)核數(shù)據(jù)結(jié)構(gòu),和PCB一樣,地址空間也是需要被操作系統(tǒng)管理的:先描述再組織。 而每一個進(jìn)程都有自己的進(jìn)程地址空間,PCB內(nèi)部有一個指針指向這塊空間!

四、頁表?

共識:現(xiàn)代操作系統(tǒng)中,幾乎不做浪費空間和時間的事情!

4.1 寫時拷貝、缺頁中斷、惰性加載

頁表具體有哪些內(nèi)容呢??——>虛擬地址、物理地址、讀寫權(quán)限、標(biāo)志位(對應(yīng)的代碼和數(shù)據(jù)是否被加載到內(nèi)存中)?

讀寫權(quán)限就可以幫助我們做檢查,比方說當(dāng)前是常量字符區(qū)但是你卻想修改,就會被操作系統(tǒng)攔截,該非法請求就不會被發(fā)送到物理內(nèi)存。

標(biāo)志位就是幫助們判斷進(jìn)程的代碼和數(shù)據(jù)是否被加載到內(nèi)存中,因為我們知道我們的進(jìn)程對應(yīng)的代碼和數(shù)據(jù)是有可能處于掛起狀態(tài)的(還沒加載到內(nèi)存)。

惰性加載:其實就是需要多少就加載多少。操作系統(tǒng)對大文件是可以實現(xiàn)分批加載,也就是說當(dāng)前的進(jìn)程可能只有PCB在內(nèi)存中,但是代碼和數(shù)據(jù)可能還沒馬上加載進(jìn)來。

缺頁中斷:在執(zhí)行進(jìn)程的時候如果發(fā)現(xiàn)標(biāo)記位顯示當(dāng)前代碼和數(shù)據(jù)沒有加載起來,就會發(fā)生缺頁中斷,也就是暫時中斷這個進(jìn)程,然后等代碼和數(shù)據(jù)加載進(jìn)來之后,再恢復(fù)原來的狀態(tài)繼續(xù)運行。

問題:一次加載進(jìn)去不是更快嗎,為什么需要檢測了之后才通過缺頁中斷加載進(jìn)去??

——> 一方面是因為可能這個文件特別大,所以沒辦法一次加載進(jìn)去,就算是可以一次加載進(jìn)去,可是你用不也是一點點去用么?? 所以缺頁中斷解決的是初步局部性加載的問題,能夠更合理的去使用內(nèi)存?。?/p>

寫時拷貝:數(shù)據(jù)區(qū)的數(shù)據(jù)是按道理是可寫的,但是一開始權(quán)限會被設(shè)置成只讀(意思就是當(dāng)前父子進(jìn)程共享),一旦父子進(jìn)程任意一方嘗試做修改的時候,發(fā)現(xiàn)當(dāng)前的數(shù)據(jù)是只讀的(但是這里不做異常處理,而是轉(zhuǎn)而發(fā)生寫時拷貝),然后開辟一塊新的物理內(nèi)存,修改頁表的映射

4.2 進(jìn)程地址空間是如何切換的

? ? ? ?進(jìn)程PCB結(jié)構(gòu)體里有對應(yīng)的進(jìn)程地址空間指針,所以進(jìn)程切換就以為這進(jìn)程空間地址空間被切換,而頁表會被存儲在CPU的cr3寄存器中,這其實屬于進(jìn)程的上下文信息,在進(jìn)程切換的時候會被進(jìn)程帶走,后面再恢復(fù)過來?。?/p>

4.3?進(jìn)程創(chuàng)建的具體過程分析

? ? ? 進(jìn)程被創(chuàng)建的時候,優(yōu)先加載的是PCB結(jié)構(gòu)體以及里面對應(yīng)的進(jìn)程地址空間結(jié)構(gòu)體,然后他的代碼和數(shù)據(jù)可能不會馬上被加載進(jìn)來。

4.4 再次理解進(jìn)程具有獨立性?

1、在內(nèi)核數(shù)據(jù)結(jié)構(gòu)上是獨立的

2、物理內(nèi)存中加載的代碼和數(shù)據(jù),只需要再頁表上去體現(xiàn)。虛擬地址可以一樣,但是通過頁表映射不同的物理地址,就可以讓父子進(jìn)程解耦,一旦發(fā)生了任何異常,你釋放你的我釋放我的。

3、通過頁表的虛擬地址映射物理地址,可以隨便取地址,甚至是亂序。但是虛擬地址可以將一個線性的地址呈現(xiàn)給進(jìn)程。

五、為什么要有進(jìn)程地址空間?(重點)?

所以我們可以對進(jìn)程進(jìn)行一個再總結(jié):

?講個故事1:?

? ? ? ? ?一個大富翁(操作系統(tǒng))有10億美金,而他有四個私生子,但是四個私生子(進(jìn)程)都并不知道對方的存在,所以他們都認(rèn)為大富翁只有他唯一一個兒子,而大富翁告訴他們一旦自己去世了,就把所有的家產(chǎn)留給他,所以每個兒子也都信了,所以大富翁其實給每個私生子都畫了一個大餅(進(jìn)程地址空間)。每個人都認(rèn)為自己有十億家產(chǎn)。 但實際上是這些私生子要多少才會給多少(進(jìn)程需要多少空間操作系統(tǒng)就給多少空間)

?結(jié)論1:讓進(jìn)程以統(tǒng)一的視角看待內(nèi)存?? ? ?這樣我進(jìn)程就不需要關(guān)心說具體應(yīng)該放在物理內(nèi)存的什么位置,也不需要關(guān)心當(dāng)前這個物理內(nèi)存是否會影響別人的數(shù)據(jù),這些工作都由操作系統(tǒng)去完成。

?故事2:

? ? ? ? ?你過年的時候經(jīng)常有壓歲錢,但是你還小所以你經(jīng)常會買到一些沒有用的東西,于是你的媽媽就讓你把錢交給他保管,等你需要買什么的時候,他再把錢給你,比如說當(dāng)你想要買個一塊錢的橡皮時,你媽媽就給了你一塊錢,但如果你想花100塊錢買個游戲機(jī)的時候,你的媽媽就不給你買,所以這個過程其實媽媽的作用就是會阻止你做一些不太適合的事情。

結(jié)論2:增加虛擬地址空間,可以讓我們訪問的時候增加一個轉(zhuǎn)換的過程,在這個轉(zhuǎn)化的過程中我們可以對我們的尋址進(jìn)行審查,所以一旦異常訪問,直接攔截,該請求就不會到達(dá)物理內(nèi)存,從而保護(hù)物理內(nèi)存

結(jié)論3:因為有地址空間和頁表的存在,將進(jìn)程管理模塊和內(nèi)存模塊進(jìn)行解耦合?!

? ? ? ? 申請物理內(nèi)存的哪一塊?優(yōu)先加載可執(zhí)行程序的哪一部分??又或者頁表填寫到什么地方??這是有Linux的內(nèi)存模塊去管理的,進(jìn)程并不需要關(guān)心。

結(jié)論4:其實變量名在定義的時候就已經(jīng)被轉(zhuǎn)化成一個個虛擬地址了,而我們之所以有a和&a,本質(zhì)上是為了區(qū)分想獲取的是變量的值還是地址。

結(jié)論5:以前我們所學(xué)習(xí)的C內(nèi)存管理,其實本質(zhì)上是進(jìn)程地址空間,而內(nèi)存管理是由Linux替我們完成的,我們上層語言并不需要關(guān)心具體的細(xì)節(jié),只需要正常去通過對應(yīng)的線性地址去使用就行了。

六、命令行參數(shù)和環(huán)境變量在棧的上面

?

?所以環(huán)境變量和命令行參數(shù)是在棧之上的一個獨立空間。 所以為什么子進(jìn)程可以繼承父進(jìn)程的環(huán)境變量,因為子進(jìn)程啟動時,父進(jìn)程已經(jīng)把對應(yīng)的環(huán)境變量信息加載進(jìn)去了, 他也是地址空間的一部分,所以他必然有頁表去幫助我們建立虛擬地址和物理地址的映射,而當(dāng)子進(jìn)程創(chuàng)建的時候,子進(jìn)程也會將父進(jìn)程虛擬地址空間當(dāng)中的環(huán)境變量的相關(guān)參數(shù)也給我們建立了一份映射,所以即使你傳參數(shù),子進(jìn)程也照樣能夠獲得父進(jìn)程的環(huán)境變量信息。

我們目前所關(guān)注的是用戶空間。?

柚子快報邀請碼778899分享:Linux:進(jìn)程地址空間

http://yzkb.51969.com/

精彩鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19544911.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄