chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux程序地址空間詳解

dyquk4xk2p3d ? 來(lái)源:入門(mén)小站 ? 2023-03-26 10:39 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1 代碼感受

在正式講程序[地址空間]前我們先來(lái)看一段簡(jiǎn)單的代碼來(lái)分析分析:

1#include
2#include
3usingnamespacestd;
4
5intg_val=100;
6
7intmain()
8{
9pid_tid=fork();
10if(id==0)
11{
12//child
13while(true)
14{
15cout<<"我是一個(gè)子進(jìn)程,我的pid是:"<

大家可以自己先分析一下結(jié)果。

我們來(lái)運(yùn)行一下結(jié)果:

01d0501a-ca69-11ed-bfe3-dac502259ad0.png

大家看前面幾行可能就會(huì)立馬發(fā)現(xiàn)問(wèn)題:我們定義的 g_val 是全局變量,當(dāng)子進(jìn)程修改 g_val 的值時(shí)我們發(fā)現(xiàn)父進(jìn)程的 g_val 是不受影響的,那么說(shuō)明父子進(jìn)程所用的 g_val 并不是同一個(gè)變量(這個(gè)很好理解,之前的我們說(shuō)過(guò)父子進(jìn)程是相互獨(dú)立的,互相不受干擾的),但是問(wèn)題出現(xiàn)在最后一列,我們驚奇的發(fā)現(xiàn)居然父子進(jìn)程的 g_val 變量的地址居然是相同的,前面不是說(shuō)父子進(jìn)程的 g_val 不是同一個(gè)變量嗎?這里為啥打印出來(lái)的地址會(huì)是相同的呢?

這里就說(shuō)明我們打印出來(lái)的地址并不是真正的[物理地址],我們語(yǔ)言層面打印出的地址叫做虛擬地址或者線性地址。我們?cè)谟肅/C++語(yǔ)言所看到的地址,全部都是虛擬地址!而物理地址,用戶一概看不到,由OS統(tǒng)一管理 。OS必須負(fù)責(zé)將虛擬地址轉(zhuǎn)化成物理地址。

2 進(jìn)程地址空間

首先我們來(lái)講一個(gè)故事:從前有一個(gè)企業(yè)家很有錢(qián),他的家產(chǎn)大概有一億美金左右的樣子。他有 4 個(gè)私生子,并且這四個(gè)私生子互相并不知道對(duì)方的存在。第一個(gè)私生子是個(gè)學(xué)霸,在國(guó)內(nèi)頂尖學(xué)校上學(xué),這個(gè)富豪便對(duì)他說(shuō),你要好好讀書(shū),將來(lái)我這一億美金全部都是你的;第二個(gè)私生子是一個(gè)三線演員,富豪便對(duì)他說(shuō),我?guī)湍愦蜷_(kāi)你紅的渠道,你不要辜負(fù)了我對(duì)你的期望,好好努力,將來(lái)我這一億美金都是你的;第 3 個(gè)私生子是個(gè)女兒,當(dāng)?shù)氖切W(xué)老師,富豪便對(duì)他說(shuō),你也不用太過(guò)努力工作,我就你這一個(gè)女兒,等我老了這一億美金就是你的了;第四個(gè)私生子是一個(gè)初中的小混混,富豪對(duì)他說(shuō),你只要好好聽(tīng)我的話,這一億美金就是你的了。

富豪給每個(gè)私生子都做出了承諾要將一億美金給他們,但是實(shí)際富豪并沒(méi)有那么多的錢(qián)給每個(gè)私生子一億美金,而這一億美金就是富豪給私生子們畫(huà)的一張大餅,但是它的私生子們卻信以為真。

那這個(gè)故事與我們講的知識(shí)有什么關(guān)系呢?其實(shí)操作系統(tǒng)就是那個(gè)富豪,私生子們就是一個(gè)一個(gè)的進(jìn)程,而那一億美金就是進(jìn)程地址空間。

PS: 我們?cè)谏钪幸M量少畫(huà)餅。

操作系統(tǒng)給進(jìn)程畫(huà)了一張大餅,操作系統(tǒng)的資源是有限的,所以他就得要好好的把這張餅給管理起來(lái),不讓這些進(jìn)程亂來(lái),而如何管理呢?

那就要先描述,再組織,Linux 中用的是一種叫做 mm_struct 的內(nèi)核數(shù)據(jù)結(jié)構(gòu)來(lái)管理的。

我們來(lái)用一張圖帶大家來(lái)看看程序地址空間:

02f7097a-ca69-11ed-bfe3-dac502259ad0.png

這張圖相信大家多多少少也不會(huì)陌生,在 C 語(yǔ)言的學(xué)習(xí)中我們也見(jiàn)到了很多次。

那么程序地址空間如何編碼的呢?(32 位的平臺(tái)下[虛擬地址]空間大概是 4GB)

ps: 下面圖每個(gè)小空格代表著一個(gè)字節(jié)。

03145214-ca69-11ed-bfe3-dac502259ad0.png

所以從這里我們也不難看出為啥虛擬地址也叫做線性地址。那么我們究竟是如何管理虛擬地址空間的每個(gè)區(qū)的呢?

我們可以用下面這種方式來(lái)描述管理:

structmm_struct
{
longcode_start;
longcode_end;
longinit_start;
longinit_end;
…………
longbrk_start;
longbrk_end;
longstack_start;
longstack_end;
}

而_start 和_end 限定的區(qū)域就是叫做虛擬地址(線性地址)

那么問(wèn)題來(lái)了,既然上面我們講了那么多虛擬地址,真正的物理地址又在哪里呢?

我們畫(huà)一個(gè)圖方便大家理解:

035326ba-ca69-11ed-bfe3-dac502259ad0.png

通過(guò)這張圖大家并不難發(fā)現(xiàn),我們?cè)谡Z(yǔ)言層面上的地址是地址空間的虛擬地址,而虛擬地址要與物理地址建立映射,就需要一張頁(yè)表(頁(yè)表的工作原理我們將放到后面來(lái)講)。

我們?cè)趯W(xué)習(xí) C 語(yǔ)言時(shí)大家在書(shū)上看到這樣的一句代碼:const char* str="hello world";

這時(shí)書(shū)上會(huì)告訴大家這句 str 指向的內(nèi)容是只讀的,不可修改的,但是這時(shí)為什么呢?這時(shí)我們就可以自己來(lái)分析分析:str 指向的內(nèi)容是在常量字符區(qū),當(dāng)常量字符區(qū)通過(guò)頁(yè)表與物理地址建立映射時(shí)在頁(yè)表中就將該數(shù)據(jù)設(shè)置為只讀,當(dāng)我們后續(xù)有修改操作時(shí)就會(huì)直接報(bào)錯(cuò)。

有了上面的基礎(chǔ)我們就可以來(lái)解釋解釋為啥開(kāi)頭我們的 g_val 是同一個(gè)地址,但是指向的內(nèi)容卻不相同的問(wèn)題了:

037def76-ca69-11ed-bfe3-dac502259ad0.png

當(dāng)不修改數(shù)據(jù)時(shí)就不會(huì)發(fā)生寫(xiě)時(shí)拷貝,父子進(jìn)程指向的是同一塊物理空間 (為了節(jié)約資源);當(dāng)要修改數(shù)據(jù)時(shí)就會(huì)發(fā)生寫(xiě)時(shí)拷貝,父子進(jìn)程指向的是不同的物理空間,但是虛擬地址空間是相等的。

我們?cè)賮?lái)回答為啥 fork 會(huì)有兩個(gè)返回值的問(wèn)題就很容易了,就是因?yàn)楦缸舆M(jìn)程的返回值是不同的,所以肯定會(huì)發(fā)生寫(xiě)時(shí)拷貝將不同的返回值用相同的虛擬地址來(lái)進(jìn)行返回,雖然虛擬地址是相同的,但是他們通過(guò)頁(yè)表建立映射的關(guān)系卻是不一樣的。

到目前為止,程序地址空間的基本內(nèi)容已經(jīng) ok, 接下來(lái)給出一些擴(kuò)展。

3 擴(kuò)展

首先引出一個(gè)問(wèn)題:假如沒(méi)有程序地址空間,OS 是如何工作的?

我們知道如果沒(méi)有了地址空間,那么 cpu 將直接跟物理地址打交道,這樣做的后果是什么?

我們不難知道假如 cpu 直接跟物理地址打交道的話那么當(dāng)我們從 cpu 中讀到非法地址時(shí)那就壞了,通過(guò)非法地址將我們程序中其他變量的值給修改了那不就扯淡了嗎。所以我們要通過(guò)一層屏障來(lái)保護(hù)數(shù)據(jù),而這一層保護(hù)就是通過(guò)程序地址空間來(lái)進(jìn)行的,當(dāng)我們?cè)L問(wèn)的數(shù)據(jù)非法時(shí)通過(guò)頁(yè)表的映射就會(huì)拒絕你的非法操作。

所以我們得出了程序地址空間的第一個(gè)好處:防止地址隨意訪問(wèn),保護(hù)物理內(nèi)存和其他進(jìn)程。

在向大家提出一個(gè)小問(wèn)題:當(dāng)我們?cè)诙焉?new 空間時(shí) OS 是立馬就把空間給你,還是等你需要的時(shí)候再給你?

這個(gè)問(wèn)題大家應(yīng)該都能夠答對(duì),與我們想得一樣,OS 會(huì)在我們需要該空間的時(shí)候再去在堆上申請(qǐng)。

03db0d0a-ca69-11ed-bfe3-dac502259ad0.png

而頁(yè)表暫時(shí)沒(méi)有與物理內(nèi)存建立映射關(guān)系稱作頁(yè)表中斷,當(dāng)我們需要空間的時(shí)候再與 · 物理內(nèi)存建立映射。大家從這張圖看出來(lái)沒(méi)有,當(dāng)我們通過(guò)頁(yè)表建立映射時(shí)將進(jìn)程管理與內(nèi)存管理給解耦合了。我進(jìn)程管理不需要關(guān)心你是怎樣在內(nèi)存上申請(qǐng)空間的,內(nèi)存管理也不需要關(guān)心進(jìn)程是如何管理起來(lái)的,這樣下來(lái)維護(hù)成本就會(huì)變得更低,維護(hù)效率會(huì)更加高效一些。

所以我們得出了程序地址空間的第二個(gè)好處:將進(jìn)程管理與內(nèi)存管理進(jìn)行解耦合。

再提出一個(gè)問(wèn)題:程序在被編譯的時(shí)候沒(méi)有被加載到內(nèi)存,那么程序內(nèi)有沒(méi)有地址呢?

答案是有的。源代碼再被編譯的時(shí)候就是按照虛擬地址空間的方式將對(duì)應(yīng)的代碼和數(shù)據(jù)進(jìn)行編制,編譯器也會(huì)遵守虛擬地址的規(guī)則。

當(dāng)我們把程序加載到內(nèi)存,程序里保存的地址(虛擬地址,并不是程序本身在內(nèi)存中的物理地址) 就會(huì)被 cpu 讀取, cpu 通過(guò)虛擬地址找到對(duì)應(yīng)的虛擬地址空間,然后虛擬地址空間又通過(guò)頁(yè)表映射到物理內(nèi)存中,這樣就將程序的整個(gè)運(yùn)轉(zhuǎn)給聯(lián)系起來(lái)了。

所以我們得出了程序地址空間的第三個(gè)好處:可以讓進(jìn)程以統(tǒng)一的視角看待自己的代碼和數(shù)據(jù)。

最近很多小伙伴找我要一些程序員必備資料,于是我翻出了壓箱底的寶藏,免費(fèi)分享給大家!

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    4

    文章

    1428

    瀏覽量

    42240
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11576

    瀏覽量

    216689
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    7261

    瀏覽量

    127905
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3832

    瀏覽量

    84375
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4922

    瀏覽量

    72255

原文標(biāo)題:Linux:程序地址空間--原來(lái)操作系統(tǒng)也喜歡畫(huà)大餅

文章出處:【微信號(hào):良許Linux,微信公眾號(hào):良許Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Linux內(nèi)核地址映射模型與Linux內(nèi)核高端內(nèi)存詳解

    Linux 操作系統(tǒng)和驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間,應(yīng)用程序運(yùn)行在用戶空間,兩者不能簡(jiǎn)單地使用指針傳遞數(shù)據(jù),因?yàn)?/div>
    發(fā)表于 05-08 10:33 ?3691次閱讀
    <b class='flag-5'>Linux</b>內(nèi)核<b class='flag-5'>地址</b>映射模型與<b class='flag-5'>Linux</b>內(nèi)核高端內(nèi)存<b class='flag-5'>詳解</b>

    Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解

    #《Linux設(shè)備驅(qū)動(dòng)開(kāi)發(fā)詳解》電子書(shū)連載#第8章 Linux設(shè)備驅(qū)動(dòng)中的阻塞與非阻塞IO,阻塞和非阻塞I/O是設(shè)備訪問(wèn)的兩種不同模式,驅(qū)動(dòng)程序可以靈活地支持用戶
    發(fā)表于 06-25 15:14

    基于嵌入式Linux應(yīng)用程序開(kāi)發(fā)詳解

    基于嵌入式Linux應(yīng)用程序開(kāi)發(fā)詳解
    發(fā)表于 10-25 14:17 ?12次下載
    基于嵌入式<b class='flag-5'>Linux</b>應(yīng)用<b class='flag-5'>程序</b>開(kāi)發(fā)<b class='flag-5'>詳解</b>

    基于嵌入式Linux的LCD驅(qū)動(dòng)程序設(shè)計(jì)

    Linux有內(nèi)核空間和用戶空間,平時(shí)工作在保護(hù)模式,每個(gè)應(yīng)用程序進(jìn)程都有自己的虛擬地址空間,應(yīng)用
    發(fā)表于 07-27 07:31 ?1846次閱讀
    基于嵌入式<b class='flag-5'>Linux</b>的LCD驅(qū)動(dòng)<b class='flag-5'>程序</b>設(shè)計(jì)

    如何為Linux編寫(xiě)用戶空間設(shè)備驅(qū)動(dòng)程序

    了解如何為Linux編寫(xiě)用戶空間設(shè)備驅(qū)動(dòng)程序。 用戶空間驅(qū)動(dòng)程序為某些設(shè)備提供內(nèi)核空間驅(qū)動(dòng)
    的頭像 發(fā)表于 11-22 07:04 ?4195次閱讀

    高端內(nèi)存的詳解linux用戶空間與內(nèi)核空間

    Linux 操作系統(tǒng)和驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間,應(yīng)用程序運(yùn)行在用戶空間,兩者不能簡(jiǎn)單地使用指針傳遞數(shù)據(jù),因?yàn)?/div>
    發(fā)表于 04-28 17:33 ?1221次閱讀
    高端內(nèi)存的<b class='flag-5'>詳解</b>:<b class='flag-5'>linux</b>用戶<b class='flag-5'>空間</b>與內(nèi)核<b class='flag-5'>空間</b>

    Linux用戶空間與內(nèi)核空間

    應(yīng)用程序運(yùn)行在用戶空間,而Linux 驅(qū)動(dòng)屬于內(nèi)核的一部分,因此驅(qū)動(dòng)運(yùn)行于內(nèi)核空間。當(dāng)我們?cè)谟脩?b class='flag-5'>空間想要實(shí)現(xiàn)對(duì)內(nèi)核的操作,比如使用open
    發(fā)表于 05-20 10:58 ?1200次閱讀
    <b class='flag-5'>Linux</b>用戶<b class='flag-5'>空間</b>與內(nèi)核<b class='flag-5'>空間</b>

    深入淺出Linux的進(jìn)程地址空間

    我們知道,在32位機(jī)器上linux操作系統(tǒng)中的進(jìn)程的地址空間大小是4G,其中0-3G是用戶空間,3G-4G是內(nèi)核空間。其實(shí),這個(gè)4G的
    的頭像 發(fā)表于 06-20 09:57 ?2231次閱讀

    Linux操作系統(tǒng)知識(shí)講解:走進(jìn)linux 內(nèi)存地址空間

    Linux操作系統(tǒng)知識(shí)講解:走進(jìn)linux 內(nèi)存地址空間
    的頭像 發(fā)表于 08-28 10:45 ?5596次閱讀
    <b class='flag-5'>Linux</b>操作系統(tǒng)知識(shí)講解:走進(jìn)<b class='flag-5'>linux</b> 內(nèi)存<b class='flag-5'>地址</b><b class='flag-5'>空間</b>

    PCI總線地址空間與系統(tǒng)地址空間的關(guān)系

    1、PCI地址空間 PCI總線具有32位數(shù)據(jù)/地址復(fù)用總線,所以其存儲(chǔ)地址空間為2的32次方=4GB。也就是PCI上的所有設(shè)備共同映射到這4
    的頭像 發(fā)表于 01-06 08:30 ?2902次閱讀

    為什么進(jìn)程地址空間中要包括操作系統(tǒng)(內(nèi)核)呢?

    這張圖就是Linux程序運(yùn)行起來(lái)后所謂的進(jìn)程地址空間,這里包括我們熟悉的代碼區(qū)、數(shù)據(jù)區(qū)、以及堆區(qū)和棧區(qū)。
    的頭像 發(fā)表于 04-18 09:09 ?1581次閱讀

    Linux操作系統(tǒng)中程序地址空間詳解

    在正式講程序[地址空間]前我們先來(lái)看一段簡(jiǎn)單的代碼來(lái)分析分析。
    發(fā)表于 09-12 10:56 ?825次閱讀
    <b class='flag-5'>Linux</b>操作系統(tǒng)中<b class='flag-5'>程序</b><b class='flag-5'>地址</b><b class='flag-5'>空間</b><b class='flag-5'>詳解</b>

    Linux系統(tǒng)為什么需要引入虛擬地址

    Linux 系統(tǒng)中,采用了虛擬內(nèi)存管理技術(shù),事實(shí)上大多數(shù)現(xiàn)在操作系統(tǒng)都是如此!在 Linux 系統(tǒng)中,每一個(gè)進(jìn)程都在自己獨(dú)立的地址空間中運(yùn)行,在32 位系統(tǒng)中,每個(gè)進(jìn)程的邏輯
    的頭像 發(fā)表于 10-07 17:28 ?1436次閱讀
    <b class='flag-5'>Linux</b>系統(tǒng)為什么需要引入虛擬<b class='flag-5'>地址</b>

    Linux虛擬地址空間和物理地址空間的關(guān)系

    過(guò)程,這其實(shí)也是MMU的工作原理。 我們知道,在Linux中,每個(gè)進(jìn)程都有自己獨(dú)立的地址空間,且互不干擾。每個(gè)進(jìn)程的地址空間又分為用戶
    的頭像 發(fā)表于 10-08 11:40 ?1919次閱讀
    <b class='flag-5'>Linux</b>虛擬<b class='flag-5'>地址</b><b class='flag-5'>空間</b>和物理<b class='flag-5'>地址</b><b class='flag-5'>空間</b>的關(guān)系

    linux驅(qū)動(dòng)程序運(yùn)行在什么空間

    Linux 驅(qū)動(dòng)程序是操作系統(tǒng)的一部分,負(fù)責(zé)管理硬件設(shè)備與操作系統(tǒng)之間的交互。驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間(Kernel Space),這是操作系統(tǒng)的核心部分,與用戶
    的頭像 發(fā)表于 08-30 14:37 ?1103次閱讀