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

【看表情包學Linux】進程地址空間 | 區(qū)域和頁表 | 虛擬地址空間 | 初識寫時拷貝

這篇具有很好參考價值的文章主要介紹了【看表情包學Linux】進程地址空間 | 區(qū)域和頁表 | 虛擬地址空間 | 初識寫時拷貝。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統???爆笑教程????《看表情包學Linux》???猛戳訂閱????

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

?? 寫在前面:本章核心主題為?"進程地址空間",會通過驗證 Linux 進程的地址空間來開頭,拋出 "同一個值能有不同內容" 的現象,通過該現象去推導出 "虛擬地址" 的概念。然后帶著大家理解為什么虛擬地址不能是物理內存、講解進程地址空間的概念以及如何設計。講解什么是區(qū)域,對區(qū)域的理解,再引出內核中的數據結構是如何維護的,如何加載的問題。最后我們會揭秘文章開頭的驗證拋出的問題,從而引出 "寫時拷貝" 的概念。講解完寫時拷貝后,我們就能理解為什么 "同一個值能有不同內容"的現象,并且也能解釋本專欄進程開篇時拋出的 "fork為什么會有兩個返回值" 的問題了。文章的最后我們再探討一下虛擬地址空間存在的意義,會印證 "進程本身是有獨立性的" 概念。

???linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統???本篇博客全站熱榜排名:14


0x00 引入:地址空間是內存嗎?非也!

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統程序地址空間是內存嗎?不是!程序地址空間不是內存!

其實,我們稱之為程序地址空間都不準確,應該叫 進程地址空間,這是一個系統級的概念!

0x01 驗證:Linux 進程地址空間

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統我們來寫個代碼驗證一下 Linux 進程地址空間!

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

??? 代碼:Linux 進程地址空間

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int un_g_val;
int g_val = 100;

int main(int argc, char* argv[], char* env[])
{
    printf("code addr            : %p\n", main);
    printf("init global addr     : %p\n", &g_val);
    printf("uninit global addr   : %p\n", &un_g_val);

    char* m1 = (char*)malloc(100);

    printf("heap addr            : %p\n", m1);
    printf("stack addr           : %p\n", &m1);

    int i = 0;
    for (i = 0; i < argc; i++) {
        printf("argv addr        : %p\n", argv[i]);   
    }

    for (i = 0; env[i]; i++) {
        printf("env addr         : %p\n", env[i]);
    }
}

?? 運行結果如下:

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

我們發(fā)現,整體的地址是依次增大的。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?請注意,堆和棧之間能觀察到有非常大的地址鏤空。

下面我們來驗證一下堆和棧的 "擠壓式" 增長方向的問題,在剛才的代碼中我們加上如下代碼:

/* 堆上申請四塊空間 */
char* m1 = (char*)malloc(100);
char* m2 = (char*)malloc(100);
char* m3 = (char*)malloc(100);
char* m4 = (char*)malloc(100);

printf("heap addr           : %p\n", m1);
printf("heap addr           : %p\n", m2);
printf("heap addr           : %p\n", m3);
printf("heap addr           : %p\n", m4);

現在我們再驗證一下棧區(qū),?依次入棧,我們取地址將其分別打印出來:

printf("stack addr           : %p\n", &m1);
printf("stack addr           : %p\n", &m2);
printf("stack addr           : %p\n", &m3);
printf("stack addr           : %p\n", &m4);

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統我們發(fā)現,堆區(qū)向地址增大方向增長,棧區(qū)向地址減少方向增長。

"堆和棧相對而生"

我們一般在 C 函數中定義的變量,通常在棧上保存,那么先定義的一定是地址比較高的,

后定義的地址一定是比較低的。因為先定義的先入棧,后定義的后入棧。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統我們再來理解一下 static 變量,如何理解 static 變量?

我們知道:一個變量在函數內被定義,如果聲明其為?static,那么它的作用域不變,但它的生命周期會隨著程序存在一直存在。

憑什么在函數內定義 static 變量,該變量就能壽與天齊了?

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

我們可以加入一個 static 變量進剛才的代碼中,我們來觀察觀察:

static int s = 100;

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

我們的 s 是被初始化的,所以就被當成了全局變量,它只是一個寫在函數內的全局變量。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?這也就是為什么它能夠壽與天齊,因為它本來就是全局變量。

?? 結論:函數內定義的變量用 static 修飾,本質是編譯器會把該變量編譯進全局數據區(qū)。

0x02 感知:地址空間的存在

?? 我們還是寫代碼去觀察分析:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int g_val = 100;
int main(void) 
{
    pid_t id = fork();
    if (id == 0) {
        // child
        while (1) {
            printf("我是子進程: %d, ppid: %d, g_val: %d, &g_val: %p\n\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);
        }
    }
    else {
        // father
        while (1) {
            printf("我是父進程: %d, ppid: %d, g_val: %d, &g_val: %p\n\n", getpid(), getppid(), g_val, &g_val);
            sleep(2);
        }
    }
}

?? 運行結果如下:

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

結論:當父子進程沒有人修改全局數據的時候,父子是共享該數據的。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?如果此時嘗試寫入,比如我們讓子進程有一個修改的操作。

我們在子進程那定義一個 flag,?sleep(1)?執(zhí)行五次,即五秒之后給它改值:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int g_val = 100;
int main(void) 
{
    pid_t id = fork();
    if (id == 0) {
        // child
        int flag = 0;
        while (1) {
            printf("我是子進程: %d, ppid: %d, g_val: %d, &g_val: %p\n\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);

            flag++;
            // 五秒之后開始更改
            if (flag == 5) {
                g_val = 200;
                printf("我是子進程,全局數據我已做修改,注意查看!\n");
            }
        }
    }
    else {
        // father
        while (1) {
            printf("我是父進程: %d, ppid: %d, g_val: %d, &g_val: %p\n\n", getpid(), getppid(), g_val, &g_val);
            sleep(2);
        }
    }
}

?? 運行結果如下:

?linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

?? 發(fā)現:父子進程讀取同一個變量(因為地址一樣),但是后續(xù)沒有人修改的情況下,父子進程讀取到的內容卻不一樣。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統? 父子進程打出來的地址是一樣的,值卻不一樣???

" 媽媽生的(即答)"

既然如此,那我就告訴你真相?—— 我們在 C/C++ 中使用的地址,絕對不是物理地址!

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

(梅開二度) 震驚,居然不是物理地址……
聽到這就像是《三體》中所說的?"物理學從來就沒有存在過" 一樣。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?如果是物理地址,上面出現的那種現象是不可能產生的!

不是物理地址,那是什么呢?本章我們還不能證明,需要后續(xù)章節(jié)的鋪墊才能夠講解。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?我們先拋出概念:我們在 C/C++ 中使用的地址,是 虛擬地址。

虛擬地址在我們 Linux 下也稱為 線性地址,有些教材中也稱之為 邏輯地址。這三個概念實際上是不一樣的,但是在 Linux 下它是一樣的(這和其本身的空間布局有關系)。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?我們再拋出一個問題:為什么我的操作系統不讓我直接看到物理內存呢?

如果能讓你直接看到物理內存,或者讓你訪問物理內存,豈不是會出亂子。

內存就是一個硬件,不能阻攔你訪問!只能被動地進行讀取和寫入!

0x03 講解:進程地址空間

每一個進程在啟動的時侯都會讓操作系統給它創(chuàng)建一個地址空間,該地址空間就是 進程地址空間

操作系統為了管理一個進程,給該進程維護一個?task_struct?叫做進程控制塊。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

首先,每一個進程都會有一個自己的進程地址空間。

操作系統要不要管理這些進程地址空間呢?當然是要管理了,我們還是引出前幾章提出的:

先描述,再組織。

所謂的進程地址空間,其實是內核的一個數據結構!叫做?mm_struct?。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?下面我們就來講解,究竟什么是地址空間!

在上一章,我們談論過進程的概念,競爭和獨立、并行和并發(fā),我們要需要談論其中的 獨立性。

進程具備獨立性,簡單來說就是一個進程掛掉或崩潰是不會波及其他進程的。

  • 進程相關的數據結構是獨立的,進程的代碼和數據是獨立的。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?說得好,但是獨立性又和地址空間有什么關系呢?我們來講個故事。

?? 小故事環(huán)節(jié):

《重生之我是財閥老板私生子》


韓國某個財閥老板非常滴有錢,他有 3 個私生子,每個私生子都并不知道對方的存在,他們都以為自己是獨生子。因為他們彼此不知道對方的存在,所以他們在生活和工作上也沒有交集,不會有任何互相的影響(這就是獨立性的體現)。財閥老板為了維護自己的獨立性:

他就對大兒子說:"兒子,你好好學習,以后老爹錢都是你的。",大兒子一聽臥槽真好,高枕無憂,就好好學習,一想到自己以后有錢,就更想學習了。

然后又對二兒子說:"兒子,好好工作,等以后我就把公司給你。",二兒子一聽熱淚盈眶,于是就好好工作,等著將來有一天可以繼承公司。

后來又對三兒子說:"兒子,你好好干活,等你長大老爹的家產交給你!",三兒子知道自己以后會繼承老爹的所有財產,開心壞了,就努力的干活。

只要在財閥爹的可承受范圍內,孩子要多少錢他都給多少錢,所以三個兒子自然都認為自己有很多錢。財閥老板給他的三個兒子畫了一張?zhí)摂M的、不存在的大餅,讓他們都能努力學習工作干活(這個步驟就是給他們分別建立了進程地址空間)。

上面的故事中,財閥老板就是操作系統,三個私生子就是進程,

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統財閥老板給他的三個兒子畫的大餅,我們就稱之為 "進程地址空間"。

所以,進程地址空間并不是物理上存在的概念,而是在邏輯上抽象的一個虛擬的空間。

財閥老板給三個私生子畫餅,就是為了維護這三個私生子互相之間的獨立性,

如果讓私生子知道自己并不是唯一,那以后分割財產必然會造成矛盾,

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統對他來說自然就不是一件好事。

所以,進程地址空間,就是就是給進程畫的大餅。

進程地址空間 → 邏輯上抽象的概念 → 讓每個進程都認為自己獨占系統的所有資源

?? 概念:操作系統通過軟件的方式,給進程提供一個軟件視角,認為自己是獨占系統的所有資源(內存)。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

0x04 理解:區(qū)域和頁表

什么叫做區(qū)域?我們來拿一張桌子來理解,初中的時候我和我的同桌分過 "38線" 。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

我們把一張桌子分為兩個區(qū)域,對桌子進行區(qū)域劃分:

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

比如,既然要標出區(qū)域,定義一個桌面區(qū)域,其實用兩個變量就可以表示了:

struct destop_area {
    int start;   // 區(qū)域起始位置
    int end;     // 區(qū)域結束位置
};

struct destop_area A = {1,50};
struct destop_area B = {50, 100};

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

搶地盤對桌面區(qū)域進行劃分,調整區(qū)域的大小只需要讓?end 加上?"調整值" 就行。

這就是區(qū)域的概念,我們只需要定義 start 和 end 就可以表示了。

每個區(qū)域范圍都是可以有對應的編號的,比如以厘米為單位,我的修正帶就放在了 50cm。

我們的?mm_struct 里面不就是區(qū)域范圍嗎?所以?mm_struct 就可以靠 start 和 end 定義:

struct mm_struct {
    long code_start;
    long code_end;
    
    long init_start;
    long init_end;
    
    long uninit_start;
    long uninit_end;
    
    long heap_start;
    long heap_end;
    
    long stack_start;
    long stack_end;
    ...
}

程序加載到內存,由程序變成進程后,由操作系統給每個進程構建的一個頁表結構,就是 頁表。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統我們來看看內核代碼,就是用一個 start 一個 end 來呈現區(qū)域空間。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

每個區(qū)域都有一個 start 和 end,它們之間就有了地址,地址我們稱之為虛擬地址,

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?然后這些虛擬地址經過頁表,就能映射到內存中了。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

0x05?揭秘:原來是寫時拷貝!

? 思考:程序是如何變成進程的?

程序被編譯出來,沒有被加載的時候,程序內部有地址嗎?有!

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?有沒有區(qū)域?也有!

?? 區(qū)分:我們程序內部的地址和內存的地址是沒有關系的。

編譯程序的時候,我們就認為程序是按照??~??進行編址的。

虛擬地址空間,不僅僅是操作系統會考慮,編譯器也會考慮。

每個進程都會創(chuàng)建一個 task_struct,每一個進程都會維護一個 mm_struct,自己有對應的區(qū)域,當我們的程序加載到內存時,程序有自己的加載到物理內存的物理地址,虛擬地址和物理地址建立映射關系,進程訪問某個區(qū)域當中的地址時,經過頁表找到對應的代碼和數據。當找到代碼和數據后,代碼加入到對應的 CPU 中,代碼中的地址在加載中就已經轉化成了線性地址/虛擬地址,所以 CPU 可以繼續(xù)照著這個邏輯向后運行。

所以剛才我們代碼測試,打印看到的虛擬地址值是一樣的,并且內容也是一樣的。在沒有人寫入的時候,虛擬地址到物理地址之間映射的頁表是一樣的,所以指向的代碼和數據都是一樣的。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

因為進程具有獨立性,比如如果此時子進程把變量改了(寫入),就會導致父進程識別的問題就出現了父進程和子進程不一的情況,因為進程是具有獨立性的,所以我們就要做到互不影響。我們的子進程要進行修改了,影響到父進程怎么辦?沒關系!操作系統會出手!當我們識別到子進程要修改時,操作系統會重新給子進程開辟一段空間,并且把 100 拷貝下來,重新給進程建立映射關系,所以子進程的頁表就不再指向父進程所對應的 100 了,而直接指向新的 100。你在做修改時又把它的值從 100 改成 200 時,我們就出現了 "改的時候永遠改的是頁表的右側,左側不變" 的情況,所以最后你看到了父子進程的虛擬地址一樣,但是經過頁表映射到了不同的物理內存,所以了你看到了一個是 100 一個是 200,父子進程的數據不同的結果。

我們的操作系統當我們的父子對數據進行修改時,操作系統會給修改的一方重新開辟一塊空間,并且把原始數據拷貝到新空間當中,這種行為就是 寫時拷貝!

當父子有任何一個進程嘗試修改對應變量時,有一個人想修改,就會觸發(fā)寫時拷貝,讓他去拷貝新的物理內存,這只需要重新構建也表的映射關系,虛擬地址是不發(fā)生任何變化的,所以最終你看的結果是虛擬地址不變,而內容不同。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統?現在再看,一點都不神奇了。

通過頁表,將父子進程的數據就可以通過寫時拷貝的方式,進行了分離。

這就做到父子進程具有獨立性,父子進程不互相影響。

0x06 回顧:fork 有兩個返回值的問題

我們在講解進程的第一個章節(jié)就提出過一個問題,關于?fork?為什么有兩個返回值的問題。

當時我們還提出了兩個問題,局限于當時還沒有講到進程地址空間,所以沒有辦法深入講解。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統我們當時說過要在 "進程地址空間" 講完后再講,現在就可以講了!

我們先回顧一下上下文:

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

?? 代碼:驗證 fork?返回值的問題,我們把 id?給打印出來:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
 
int main(void) {
    pid_t id = fork();
 
    printf("Hello, World! id: %d\n", id);
    sleep(1);
}

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統fork 有兩個返回值,pid_t id,同一個變量為什么會有兩個返回值?

本章我們就可以理解了,因為當它?return 的時候,pid_t id 是屬于父進程的??臻g中定義的。

fork?內部?return?會被執(zhí)行兩次,return?的本質就是通過寄存器將返回值寫入到接收返回值的變量中。當我們的?id = fork()?時,誰先返回,誰就要發(fā)生?寫時拷貝。所以,同一個變量會有不同的返回值,本質是因為大家的虛擬地址是一樣的,但大家的物理地址是不一樣的。

0x07 探討:為什么要有虛擬地址空間?

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統如果我們沒有虛擬地址空間,直接讓進程訪問物理內存是不安全的。

有了虛擬地址空間,就是給訪問內存添加了一層軟硬關鍵層,可以對轉化過程進行審核,非法的訪問就可以被直接攔截了,可以?保護內存。

還能夠將 進程管理 Linux 內存管理,通過地址空間進行功能模塊的解耦。

讓進程或者程序可以以一種統一的視角看待內存!

有了虛擬地址空間,還可以讓進程或者程序可以 以統一的視角看待內存。方便以統一的方式來編譯和加載所有的可執(zhí)行程序。如此一來,就可以簡化進程本身的設計和實現。

linux 頁表項和虛擬地址空間,看表情包學Linux,linux,運維,服務器,操作系統

?? [ 筆者 ]? ?王亦優(yōu)
?? [ 更新 ]? ?2023.2.14
? [ 勘誤 ]?? /* 暫無 */
?? [ 聲明 ]? ?由于作者水平有限,本文有錯誤和不準確之處在所難免,
              本人也很想知道這些錯誤,懇望讀者批評指正!

?? 參考資料?

C++reference[EB/OL]. []. http://www.cplusplus.com/reference/.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

比特科技. Linux[EB/OL]. 2021[2021.8.31 xiw文章來源地址http://www.zghlxwxcb.cn/news/detail-809163.html

到了這里,關于【看表情包學Linux】進程地址空間 | 區(qū)域和頁表 | 虛擬地址空間 | 初識寫時拷貝的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【看表情包學Linux】進程狀態(tài)解析 | 運行態(tài) | 終止態(tài) | 進程掛起與阻塞 | 運行態(tài)R | 阻塞態(tài)S/D | 死亡態(tài)X | 僵尸態(tài)Z | 暫停態(tài)T/t | 僵尸進程 | 孤兒進程

    【看表情包學Linux】進程狀態(tài)解析 | 運行態(tài) | 終止態(tài) | 進程掛起與阻塞 | 運行態(tài)R | 阻塞態(tài)S/D | 死亡態(tài)X | 僵尸態(tài)Z | 暫停態(tài)T/t | 僵尸進程 | 孤兒進程

    ?? ??? 爆笑 教程 ????《看表情包學Linux》?? ? 猛戳訂閱 ? ? ??? ?? 寫在前面: 本章我們專門講解進程的狀態(tài)。我們先學習具體的 Linux 系統狀態(tài),再去介紹 OS 學科面對的概念如何理解 —— 運行態(tài)、終止態(tài)、阻塞態(tài)以及掛起態(tài)。最后我們再把操作系統的概念對接,理

    2024年01月16日
    瀏覽(23)
  • 【看表情包學Linux】軟硬鏈接

    【看表情包學Linux】軟硬鏈接

    ????????? ??? 爆笑 Linux? 教程: ????《看表情包學Linux》 ?? ?? ?本篇博客全站熱榜排名: 9 ?? 寫在前面: 上面我們學到的所有東西,全部都是在內存中的。是不是所有的文件都被打開了呢?不是所有的文件,都被打開的,我們之前研究的是進程打開的文件,

    2024年02月02日
    瀏覽(21)
  • 【看表情包學Linux】文件描述符

    【看表情包學Linux】文件描述符

    ?? ??? 爆笑 教程 ????《看表情包學Linux》?? ? 猛戳訂閱 ? ? ?? ?? 寫在前面: 在上一章中,我們已經把 fd 的基本原理搞清楚了。本章我們將開始探索 fd 的應用特征,探索 文件描述符的分配原則。講解重定向,上一章是如何使用 fflush 把內容變出來的,介紹 dup2 函數,

    2023年04月15日
    瀏覽(17)
  • 【看表情包學Linux】軟硬鏈接 | 動靜態(tài)庫

    【看表情包學Linux】軟硬鏈接 | 動靜態(tài)庫

    ?? ??? 爆笑 教程 ????《看表情包學Linux》?? ? 猛戳訂閱 ? ? ?? ?? 寫在前面: 上一章我們講解了 inode,為文件系統收了尾,這幾章我們充分地講解完了文件系統的知識點,現在我們開始開始學習軟硬鏈接了。如果沒有文件系統的鋪墊,想直接理解軟硬鏈接難免有些困

    2024年02月16日
    瀏覽(20)
  • 【Linux】程序地址空間?進程地址空間

    【Linux】程序地址空間?進程地址空間

    了解進程的運行: ?運行結果:我們會發(fā)現這打印的結果亂七八糟,因為它也不知道什么時候該干什么 ?我們讓代碼睡眠1秒:打印的結果就正常了 ?以前我們學習的內存管理(程序地址空間): ?為了驗證上面虛擬地址,我們運行下面代碼: (這種問題出現的原因在下面的為

    2024年02月13日
    瀏覽(21)
  • Linux: 進程地址空間究竟是什么?進程地址空間存在意義何在?

    Linux: 進程地址空間究竟是什么?進程地址空間存在意義何在?

    ?在C/C++中,我們常將內存分為: 代碼區(qū)、常量區(qū)、全局區(qū)(靜態(tài)區(qū))、堆、棧 等等。相關內存區(qū)域劃分如下:(X86, 32位平臺) 如何驗證C/C++中各區(qū)域的相對位置呢? ?我們可以在每個區(qū)域中選擇一個地址來驗證C/C++中各區(qū)域的相對位置!!具體如下: 【源代碼】: 【運行

    2024年04月08日
    瀏覽(26)
  • Linux之進程(四)(進程地址空間)

    Linux之進程(四)(進程地址空間)

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

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

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

    主頁: 醋溜馬桶圈-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)境變量相關的命令 1.5 環(huán)境變量的組織方式 1.6 通過代碼如何獲取環(huán)境變量 1.6.1 命令行第三個參數 1

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

    【Linux】進程周邊006之進程地址空間

    ? ?? 樊梓慕: 個人主頁 ??? 個人專欄: 《C語言》 《數據結構》 《藍橋杯試題》 《LeetCode刷題筆記》 《實訓項目》 《C++》 《Linux》 ?? 每一個不曾起舞的日子,都是對生命的辜負 目錄 前言 1.程序地址空間 1.1驗證地址空間的排布 ?1.2利用fork函數觀察當子進程修改某個共

    2024年02月04日
    瀏覽(43)
  • 【Linux】深挖進程地址空間

    【Linux】深挖進程地址空間

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

    2024年02月03日
    瀏覽(26)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領取紅包

二維碼2

領紅包