一、程序地址空間回顧
我們在講C語言的時候,老師給大家畫過這樣的空間布局圖
下圖是內存嗎?答案不是,它是進程/虛擬地址空間。
可是我們對他并不理解!
來段代碼感受一下
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 0;
}
else if(id == 0){ //child
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
else{ //parent
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
輸出
我們發(fā)現,輸出出來的變量值和地址是一模一樣的,很好理解呀,因為子進程按照父進程為模版,父子并沒有對變量進行進行任何修改??墒菍⒋a稍加改動:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 0;
}
else if(id == 0){ //child,子進程肯定先跑完,也就是子進程先修改,完成之后,父進程再讀取
g_val=100;
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}else{ //parent
sleep(3);
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
輸出
我們發(fā)現,父子進程,輸出地址是一致的,但是變量內容不一樣!能得出如下結論:
- 變量內容不一樣,所以父子進程輸出的變量絕對不是同一個變量
- 但地址值是一樣的,說明,該地址絕對不是物理地址!
- 在Linux地址下,這種地址叫做 虛擬地址
- 我們在用C/C++語言所看到的地址,全部都是虛擬地址!物理地址,用戶一概看不到,由OS統(tǒng)一管理。
OS必須負責將 虛擬地址 轉化成 物理地址 。
二、進程地址空間
所以之前說‘程序的地址空間’是不準確的,準確的應該說成 進程地址空間 ,那該如何理解呢?看圖:
虛擬地址空間:文章來源:http://www.zghlxwxcb.cn/news/detail-768679.html
說明:
上面的圖就足矣說名問題,同一個變量,地址相同,其實是虛擬地址相同,內容不同其實是被映射到了不同的物理地址!文章來源地址http://www.zghlxwxcb.cn/news/detail-768679.html
三、為什么要存在進程地址空間
- 讓進程以統(tǒng)一的視角看待內存,所以任意一個進程,可以通過地址空間+頁面也可以將亂序的內存數據,變得有序,分門別類的規(guī)劃好。
- 可以安全檢查。
- 將進程管理和內存管理解耦。
- 通過頁表,讓進程映射到不同的物理內存,從而實現進程的鼓勵性。
到了這里,關于Linux--程序地址空間的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!