国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Linux 進(jìn)程(五)] 程序地址空間深度剖析

這篇具有很好參考價(jià)值的文章主要介紹了[Linux 進(jìn)程(五)] 程序地址空間深度剖析。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器

1、前言

Linux學(xué)習(xí)路線比較線性,也比較長,因此一個(gè)完整的知識點(diǎn)學(xué)習(xí)就會(huì)分布在兩篇文章中,沒有連貫起來,訂閱的朋友諒解一下,再次感謝訂閱!
上一篇文章最后講到了程序地址空間分布,大家可以先復(fù)習(xí)一下上一篇文章:程序地址空間的初認(rèn)識
本片我們深度學(xué)習(xí)一下程序地址空間,虛擬地址與物理地址的關(guān)系,頁表與物理地址的映射,寫時(shí)拷貝的過程,我們帶著這些問題開始我們今天新的學(xué)習(xí)!

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

在學(xué)習(xí)地址空間前,我們要明確:C/C++看到的地址其實(shí)并不是真正的地址,它其實(shí)是 虛擬地址,真正的地址是物理地址。
我們通過一個(gè)故事來帶大家更好的理解一下什么是地址空間:
有一個(gè)大富豪,他有10億的資產(chǎn),同時(shí)擁有四個(gè)私生子,這四個(gè)私生子互相不知道其他人的存在。
私生子1是學(xué)生,私生子2是一個(gè)社會(huì)青年,私生子3是律師,私生子4是企業(yè)家。一天富豪分別對四個(gè)私生子說:
對1說:你是咱家的大學(xué)生,好好學(xué)習(xí),以后這10個(gè)億都是你的。
對2說:……,以后這10個(gè)億都是你的。
對3說:……,以后這10個(gè)億都是你的。
對4說:……,以后這10個(gè)億都是你的。
他們都各自以為自己有10個(gè)億等著繼承呢,于是他們斷斷續(xù)續(xù)的對父親說:
1:……,有用,需要xxx錢(不過10億的1/10)。父親給了。
2:……,有用,需要xxx錢(不過10億的1/10)。父親給了。
3:……,有用,需要xxx錢(不過10億的1/10)。父親給了。
4:……,有用,需要xxx錢(不過10億的1/10)。父親給了。
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器

操作系統(tǒng)對應(yīng)富豪;
內(nèi)存對應(yīng)那真實(shí)的10個(gè)億;
進(jìn)程對應(yīng)為私生子;
虛擬地址空間對應(yīng)富豪對他們每個(gè)人畫的10億的餅。
總結(jié):
地址空間其實(shí)并不是真實(shí)的,是操作系統(tǒng)給進(jìn)程畫的餅。

3、進(jìn)程地址空間的劃分

我們看一下地址空間的分布:
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器
地址空間其實(shí)就是上面各個(gè)區(qū)域結(jié)合起來,這些區(qū)域的劃分很簡單,用begin與end兩個(gè)變量一個(gè)指頭,一個(gè)指尾,來限制范圍即可。
根據(jù)以上的學(xué)習(xí),我們不難得知:雖然地址空間是操作系統(tǒng)給進(jìn)程畫的的餅,但是進(jìn)程多了這些地址空間我們也需要管理起來,要不然進(jìn)程和對應(yīng)的地址空間對應(yīng)不上。說到管理就不得不提“先描述,再組織”。Linux中,這個(gè)進(jìn)程/虛擬地址空間這個(gè)東西,叫做:

struct mm_struct
{
	long code_start; // 代碼區(qū)開始
    long code_end; // 代碼區(qū)結(jié)束
    long data_start; // 數(shù)據(jù)區(qū)開始
    long data_end; // 數(shù)據(jù)區(qū)結(jié)束
    long heap_start; // 堆區(qū)開始
    long heap_end; // 堆區(qū)結(jié)束
	long stack_start; // 棧區(qū)開始
    long stack_end; // 棧區(qū)結(jié)束
    ... // 其他屬性
}

進(jìn)程地址空間mm_struct里面其實(shí)就是維護(hù)了一張鏈表,每個(gè)節(jié)點(diǎn)是一個(gè)結(jié)構(gòu)體vm_area_struct,里面存的就是一個(gè)區(qū)域的開始和結(jié)束地址。

4、虛擬地址與物理地址的關(guān)系

我們來寫一段代碼探究一下地址:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int g_val = 100;                                                                                                                
int main()                            
{                                     
    pid_t id = fork();                
    if(id == 0)                       
    {                                 
        // child                      
        int cnt = 5;                  
        while(1)                                                                                             
        {                                                                                                    
            printf("child, Pid: %d, Ppid: %d, g_val: %d, &g_val = %p\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);                 
            if(cnt == 0)              
            {                                            
                g_val = 200;                             
                printf("child change g_val: 100->200\n");
            }                         
            cnt--;                    
        }                             
    }                                 
    else                              
    {
        // father
        while(1)
        {
            printf("father, Pid: %d, Ppid: %d, g_val = %d, &g_val = %p\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);
        }
    }

    return 0;
}

[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器
我們知道,在沒有發(fā)生對數(shù)據(jù)的改寫時(shí),父子進(jìn)程共用一份代碼和數(shù)據(jù),這里子進(jìn)程對數(shù)據(jù)進(jìn)行了修改,父子進(jìn)程讀到的值不同了,父子進(jìn)程的全局變量地址怎么還是相同的???
問題:
父子進(jìn)程對同一個(gè)地址進(jìn)行讀取,竟然讀出了不同的值?
我們這就能得出之前的結(jié)論:我們C/C++看到的地址是虛擬地址。
有了上面的理解,我們再來談?wù)勌摂M地址和物理地址的關(guān)系:
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器
經(jīng)過虛擬地址的學(xué)習(xí)以及這張圖,我們現(xiàn)在就可以解釋,同一個(gè)地址的值不同。
當(dāng)我們fork創(chuàng)建了子進(jìn)程的時(shí)候,子進(jìn)程與父進(jìn)程共享一份代碼和數(shù)據(jù),此時(shí)子進(jìn)程與父進(jìn)程進(jìn)程地址空間與頁表是一份。
當(dāng)子進(jìn)程對值進(jìn)行修改的時(shí),操作系統(tǒng)將父進(jìn)程的進(jìn)程地址空間與頁表拷貝一份給子進(jìn)程。當(dāng)寫入時(shí),產(chǎn)生寫時(shí)拷貝,重新開一塊物理地址存內(nèi)容,并將子進(jìn)程頁表中物理地址修改即可,子進(jìn)程的虛擬地址沒有變。因此父子進(jìn)程虛擬地址相同是表象,本質(zhì)物理地址已經(jīng)修改了。
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器

5、頁表的作用

頁表的結(jié)構(gòu)中還有一欄,訪問權(quán)限,我們下面看一下:
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器
根據(jù)此結(jié)構(gòu),我們知道了頁表的第一個(gè)作用:頁表的存在可以有效的進(jìn)行進(jìn)程訪問內(nèi)存的安全檢查!
我們配合一段代碼,大家更好理解:

char* str = "hello Linux";
*str = 'H';

我們都知道hello Linux是在字符常量區(qū)的,是不可被修改的,它不可被修改的本質(zhì)就是:在頁表中,訪問權(quán)限被設(shè)置為r(只讀權(quán)限)。并不是因?yàn)槭窃诖a區(qū)不可被修改,內(nèi)存是可以隨意讀寫的,因?yàn)橛许摫頇?quán)限的限制。
頁表的第二個(gè)作用:將無序變有序。
物理內(nèi)存是不分代碼區(qū),棧區(qū),堆區(qū)等的,數(shù)據(jù)在物理內(nèi)存中的存儲是無序的。
頁表的存在讓進(jìn)程以統(tǒng)一的視角看待內(nèi)存,所以任意一個(gè)進(jìn)程,可以通過地址空間+頁表可以將亂序的內(nèi)存數(shù)據(jù),變?yōu)橛行?,分門別類的規(guī)劃好!
CPU中有一個(gè)寄存器CR3,它會(huì)保存當(dāng)前進(jìn)程的頁表地址,此頁表地址直接就是物理地址。操作系統(tǒng)給用戶一個(gè)映射的頁表,是為了上面的兩個(gè)作用,它自己是不需要的。

擴(kuò)展

總結(jié):

  • 每一個(gè)進(jìn)程都是有頁表的;
  • 進(jìn)程切換,不僅僅是PCB與代碼、數(shù)據(jù)的切換,切換時(shí)還要帶走自己的進(jìn)程地址空間與頁表。

根據(jù)以上的學(xué)習(xí),我們想一下,我們的內(nèi)存只有16/32/64,但是運(yùn)行一個(gè)幾百G的大型游戲,是怎么運(yùn)行的呢?
其實(shí)并不是要把這幾百G的數(shù)據(jù)全部加載上來的,而是將數(shù)據(jù)邊加載邊執(zhí)行,對掛起的一個(gè)模塊數(shù)據(jù)與代碼先換出,然后加載需要加載的,這樣進(jìn)程在內(nèi)存中就動(dòng)態(tài)的運(yùn)行起來了。
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器
這就是地址空間的分配。當(dāng)我們其中一塊代碼被執(zhí)行完,我們可以覆蓋式的像物理內(nèi)存中重新加載內(nèi)容,或者重新開辟新的物理內(nèi)存,重新建立新的映射關(guān)系,就可以讓程序邊加載邊執(zhí)行。
頁表中,還有可能存在虛擬地址存在,其他都不存在的情況:
當(dāng)訪問到頁表的虛擬地址存在,其他內(nèi)容不存在時(shí),此時(shí)訪問暫停,操作系統(tǒng)先申請內(nèi)存,再根據(jù)虛擬地址找到那個(gè)可執(zhí)行程序,重新加載到內(nèi)存里,并把對應(yīng)的物理內(nèi)存放入頁表,這時(shí)再開始訪問,就開始運(yùn)行新加載的代碼了。這個(gè)過程叫做缺頁中斷。
[Linux 進(jìn)程(五)] 程序地址空間深度剖析,Linux,linux,運(yùn)維,服務(wù)器
我們其實(shí)也不難發(fā)現(xiàn),這背后的一切進(jìn)程是完全不知道的,是os給做的,所以頁表的第三個(gè)作用:
頁表 左邊是進(jìn)程管理,右邊是內(nèi)存管理。降低進(jìn)程管理和內(nèi)存管理的耦合度。

6、為什么要有地址空間?

通過上面的學(xué)習(xí),我們來總結(jié)一下這個(gè)問題的答案:文章來源地址http://www.zghlxwxcb.cn/news/detail-804452.html

  • 1、有效的保護(hù)了物理地址的安全。通過進(jìn)程地址空間+頁表的映射,對不合法的操作可以有效的攔截。
  • 2、將物理地址的無序變?yōu)橛行?/strong>。物理內(nèi)存是不分代碼區(qū),棧區(qū),堆區(qū)等的,數(shù)據(jù)在物理內(nèi)存中的存儲是無序的。頁表的存在讓進(jìn)程以統(tǒng)一的視角看待內(nèi)存,所以任意一個(gè)進(jìn)程,可以通過地址空間+頁表可以將亂序的內(nèi)存數(shù)據(jù),變?yōu)橛行?,分門別類的規(guī)劃好!
  • 3、降低進(jìn)程管理和物理內(nèi)存管理之間的耦合度。因?yàn)檫M(jìn)程地址空間和頁表的存在,物理內(nèi)存可以不關(guān)心數(shù)據(jù)類型,直接對數(shù)據(jù)進(jìn)行加載,這樣進(jìn)程管理與物理內(nèi)存管理就做到了解耦。
  • 4、保證進(jìn)程的獨(dú)立性。因?yàn)榈刂房臻g的存在,各個(gè)進(jìn)程都認(rèn)為所有的內(nèi)存空間都屬于自己。每個(gè)進(jìn)程都有自己的地址空間+頁表,這兩者配合實(shí)現(xiàn)了進(jìn)程的獨(dú)立性,每個(gè)不知道也不需要知道其他進(jìn)程的存在!

到了這里,關(guān)于[Linux 進(jìn)程(五)] 程序地址空間深度剖析的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Linux之進(jìn)程(四)(進(jìn)程地址空間)

    Linux之進(jìn)程(四)(進(jìn)程地址空間)

    目錄 一、程序地址空間 二、進(jìn)程地址空間 1、概念 2、寫時(shí)拷貝 3、為什么要有進(jìn)程地址空間 四、總結(jié) 我們先來看看下面這張圖。這張圖是我們在學(xué)習(xí)語言時(shí)就見到過的內(nèi)存區(qū)域劃分圖。? 下面我們在Linux下看一看內(nèi)存區(qū)域是不是也是這么劃分的。 可見在Linux下也是符合上面

    2024年02月04日
    瀏覽(23)
  • 【Linux】進(jìn)程>環(huán)境變量&&地址空間&&進(jìn)程調(diào)度

    【Linux】進(jìn)程>環(huán)境變量&&地址空間&&進(jìn)程調(diào)度

    主頁: 醋溜馬桶圈-CSDN博客 專欄: Linux_醋溜馬桶圈的博客-CSDN博客 gitee :mnxcc (mnxcc) - Gitee.com 目錄 1.環(huán)境變量 1.1 基本概念 1.2 常見環(huán)境變量? 1.3 查看環(huán)境變量方法? 1.4?和環(huán)境變量相關(guān)的命令 1.5 環(huán)境變量的組織方式 1.6 通過代碼如何獲取環(huán)境變量 1.6.1 命令行第三個(gè)參數(shù) 1

    2024年04月15日
    瀏覽(28)
  • 【Linux】進(jìn)程周邊006之進(jìn)程地址空間

    【Linux】進(jìn)程周邊006之進(jìn)程地址空間

    ? ?? 樊梓慕: 個(gè)人主頁 ??? 個(gè)人專欄: 《C語言》 《數(shù)據(jù)結(jié)構(gòu)》 《藍(lán)橋杯試題》 《LeetCode刷題筆記》 《實(shí)訓(xùn)項(xiàng)目》 《C++》 《Linux》 ?? 每一個(gè)不曾起舞的日子,都是對生命的辜負(fù) 目錄 前言 1.程序地址空間 1.1驗(yàn)證地址空間的排布 ?1.2利用fork函數(shù)觀察當(dāng)子進(jìn)程修改某個(gè)共

    2024年02月04日
    瀏覽(43)
  • 【Linux】—— 進(jìn)程地址空間

    【Linux】—— 進(jìn)程地址空間

    序言: 在上篇中,我們講解了關(guān)于進(jìn)程優(yōu)先級的概念。本期,我將給大家介紹的是關(guān)于進(jìn)程地址空間的話題。 目錄 (一)程序地址空間回顧 (二)代碼演示 (三)進(jìn)程地址空間的引入 總結(jié) 我們在學(xué)習(xí)C/C++語言的時(shí)候,大家可能都見過這樣的空間布局圖: 一個(gè)程序有哪些

    2024年02月15日
    瀏覽(25)
  • 【Linux】深挖進(jìn)程地址空間

    【Linux】深挖進(jìn)程地址空間

    作者簡介:?舊言~,目前大二,現(xiàn)在學(xué)習(xí)Java,c,c++,Python等 座右銘:松樹千年終是朽,槿花一日自為榮。 目標(biāo):熟悉【Linux】進(jìn)程地址空間 毒雞湯:也許有一天,你發(fā)覺日子特別的艱難,那可能是這次的收獲特別的巨大。 望小伙伴們點(diǎn)贊??收藏?加關(guān)注喲????? ????

    2024年02月03日
    瀏覽(26)
  • 【Linux】理解進(jìn)程地址空間

    【Linux】理解進(jìn)程地址空間

    ?? 作者: 阿潤菜菜 ?? 專欄: Linux系統(tǒng)編程 ?我們在學(xué)習(xí)C語言的時(shí)候,都學(xué)過內(nèi)存區(qū)域的劃分如棧、堆、代碼區(qū)、數(shù)據(jù)區(qū)這些。但我們其實(shí)并不真正理解內(nèi)存 — 我們之前一直說的內(nèi)存是物理上的內(nèi)存嗎? 我們先看一段測試代碼: 運(yùn)行結(jié)果: 我們可以注意到子進(jìn)程的變量

    2024年02月02日
    瀏覽(28)
  • Linux--進(jìn)程地址空間

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

    1.線程地址空間 所謂進(jìn)程地址空間(process address space),就是從進(jìn)程的視角看到的地址空間,是進(jìn)程運(yùn)行時(shí)所用到的虛擬地址的集合。 簡單地說,進(jìn)程就是內(nèi)核數(shù)據(jù)結(jié)構(gòu)和代碼和本身的代碼和數(shù)據(jù),進(jìn)程本身不能訪問物理地址,之時(shí)候就需要有一個(gè)中間媒介,就是地址空間,

    2024年02月11日
    瀏覽(21)
  • Linux:進(jìn)程地址空間

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

    目錄 1.程序地址空間? 2.進(jìn)程地址空間 我們在講C/C++語言的時(shí)候,32位平臺下,我們見過這樣的空間布局圖 我們來驗(yàn)證一下這張圖的正確性: 運(yùn)行結(jié)果: 通過觀察靜態(tài)變量的位置,可以認(rèn)為靜態(tài)變量就是全局變量,只是靜態(tài)變量只初始化一次,有作用域的限制。 這里棧區(qū)還

    2024年02月04日
    瀏覽(28)
  • 『 Linux 』進(jìn)程地址空間概念

    『 Linux 』進(jìn)程地址空間概念

    在c/C++中存在一種 內(nèi)存 的概念; 一般來說一個(gè)內(nèi)存的空間分布包括 棧區(qū) , 堆區(qū) , 代碼段 等等; 且內(nèi)存是 自底向上 (由 0x00000000 至 0xFFFFFFFF ); 以該圖為例: 該圖即為常見的內(nèi)存分布圖; 正文代碼段 正文代碼段所存放的數(shù)據(jù) 一般為函數(shù)體的二進(jìn)制代碼 ; 已初始化數(shù)據(jù)區(qū) 已初始化

    2024年02月03日
    瀏覽(21)
  • 淺析Linux進(jìn)程地址空間

    淺析Linux進(jìn)程地址空間

    現(xiàn)代處理器基本都支持虛擬內(nèi)存管理,在開啟虛存管理時(shí),程序只能訪問到虛擬地址,處理器的內(nèi)存管理單元(MMU)會(huì)自動(dòng)完成虛擬地址到物理地址的轉(zhuǎn)換?;谔摂M內(nèi)存機(jī)制,操作系統(tǒng)可以為每個(gè)運(yùn)行中的進(jìn)程創(chuàng)建獨(dú)享的虛擬地址空間,在這個(gè)空間中執(zhí)行的程序,無法感知

    2024年01月20日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包