欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux進(jìn)程地址空間詳解

 更新時(shí)間:2024年10月04日 10:45:35   作者:??小陳在拼命??  
在C語(yǔ)言編程中,內(nèi)存管理是一個(gè)重要的環(huán)節(jié),本文詳細(xì)解析了C語(yǔ)言中的內(nèi)存區(qū)域劃分,包括棧區(qū)、堆區(qū)、全局區(qū)等,并探討了fork函數(shù)的遺留問(wèn)題,即如何出現(xiàn)一個(gè)變量同時(shí)等于0又大于0的情況,此外,文章還深入討論了進(jìn)程地址空間的概念

一、C語(yǔ)言?xún)?nèi)存管理基礎(chǔ)

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

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

我們?nèi)绾悟?yàn)證這個(gè)區(qū)域的劃分是否正確呢?

可以通過(guò)代碼的方式在不同的區(qū)域創(chuàng)建變量然后來(lái)取地址獲取再進(jìn)行比較

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

驗(yàn)證棧區(qū):地址在變低

驗(yàn)證堆區(qū):地址在變高

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

二、fork遺留問(wèn)題

歷史遺留問(wèn)題:為什么一個(gè)變量可以同時(shí)等于0又同時(shí)>0 ??

實(shí)驗(yàn):

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

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

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

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

3.1 什么叫做地址空間

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

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

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

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

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

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

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

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

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

四、頁(yè)表

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

4.1 寫(xiě)時(shí)拷貝、缺頁(yè)中斷、惰性加載

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

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

標(biāo)志位就是幫助們判斷進(jìn)程的代碼和數(shù)據(jù)是否被加載到內(nèi)存中,因?yàn)槲覀冎牢覀兊倪M(jìn)程對(duì)應(yīng)的代碼和數(shù)據(jù)是有可能處于掛起狀態(tài)的(還沒(méi)加載到內(nèi)存)。

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

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

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

——> 一方面是因?yàn)榭赡苓@個(gè)文件特別大,所以沒(méi)辦法一次加載進(jìn)去,就算是可以一次加載進(jìn)去,可是你用不也是一點(diǎn)點(diǎn)去用么?? 所以缺頁(yè)中斷解決的是初步局部性加載的問(wèn)題,能夠更合理的去使用內(nèi)存!

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

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

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

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

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

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

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

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

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

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

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

講個(gè)故事1:

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

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

故事2:

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

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

結(jié)論3:因?yàn)橛械刂房臻g和頁(yè)表的存在,將進(jìn)程管理模塊和內(nèi)存模塊進(jìn)行解耦合 !

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

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

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

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

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

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

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Linux系統(tǒng)刪除文件夾和文件的命令

    Linux系統(tǒng)刪除文件夾和文件的命令

    筆者給大家介紹Linux系統(tǒng)刪除文件夾和文件的命令,很多朋友喜歡是rmdir命令來(lái)刪除文件,不過(guò)當(dāng)遇到目錄非空,就會(huì)麻煩,下面閱讀本文學(xué)習(xí)下linux刪除文件夾和文件的命令吧
    2018-02-02
  • Linux下實(shí)現(xiàn)免密碼登錄(超詳細(xì))

    Linux下實(shí)現(xiàn)免密碼登錄(超詳細(xì))

    這篇文章主要介紹了Linux下實(shí)現(xiàn)免密碼登錄的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-10-10
  • tr命令在統(tǒng)計(jì)英文單詞出現(xiàn)頻率中的妙用

    tr命令在統(tǒng)計(jì)英文單詞出現(xiàn)頻率中的妙用

    今天小編就為大家分享一篇關(guān)于tr命令在統(tǒng)計(jì)英文單詞出現(xiàn)頻率中的妙用,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • centos源碼編譯php5 mcrypt模塊步驟詳解

    centos源碼編譯php5 mcrypt模塊步驟詳解

    服務(wù)器安裝的是php5.3版本,源中沒(méi)有包含mcrypt擴(kuò)展,只有自己從源碼中編譯mcrypt模塊了,看下面的詳細(xì)步驟
    2013-12-12
  • Ubuntu Server 14.04升級(jí)Ubuntu Server 16.04

    Ubuntu Server 14.04升級(jí)Ubuntu Server 16.04

    這篇文章主要介紹了 Ubuntu Server 14.04升級(jí)Ubuntu Server 16.04,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-12-12
  • Linux運(yùn)維基礎(chǔ)進(jìn)程管理及環(huán)境組成分析

    Linux運(yùn)維基礎(chǔ)進(jìn)程管理及環(huán)境組成分析

    這篇文章主要為大家介紹了Linux運(yùn)維基礎(chǔ),對(duì)其中進(jìn)程管理及環(huán)境組成分析作了詳細(xì)的分析,有需要的朋友可以借鑒參考下,希望可以有所幫助
    2021-09-09
  • 在 Linux 中不使用 CD 命令進(jìn)入目錄/文件夾的方法

    在 Linux 中不使用 CD 命令進(jìn)入目錄/文件夾的方法

    眾所周知,如果沒(méi)有 cd 命令,我們無(wú)法 Linux 中切換目錄。接下來(lái)通過(guò)本文給大家介紹了在 Linux 中不使用 CD 命令進(jìn)入目錄/文件夾的方法,需要的朋友可以參考下
    2019-04-04
  • CentOS?6?Linux系統(tǒng)添加永久靜態(tài)路由的方法

    CentOS?6?Linux系統(tǒng)添加永久靜態(tài)路由的方法

    在Linux系統(tǒng)中,特別是對(duì)于服務(wù)器管理而言,正確配置網(wǎng)絡(luò)路由是確保網(wǎng)絡(luò)通信順暢的重要步驟,本文將介紹如何在CentOS?6系統(tǒng)中添加永久靜態(tài)路由,通過(guò)本文的學(xué)習(xí),你將能夠掌握如何在不影響現(xiàn)有網(wǎng)絡(luò)配置的情況下,為你的系統(tǒng)添加一條或多條靜態(tài)路由,需要的朋友可以參考下
    2025-03-03
  • linux下快速列出局域網(wǎng)中所有主機(jī)名(計(jì)算機(jī)名)的腳本

    linux下快速列出局域網(wǎng)中所有主機(jī)名(計(jì)算機(jī)名)的腳本

    這篇文章主要介紹了linux下快速列出局域網(wǎng)中所有主機(jī)名(計(jì)算機(jī)名)的腳本,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • linux vi命令知識(shí)點(diǎn)用法總結(jié)

    linux vi命令知識(shí)點(diǎn)用法總結(jié)

    在本篇文章里小編給大家整理的是關(guān)于linux vi命令的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們參考學(xué)習(xí)下。
    2019-10-10

最新評(píng)論