Linux進程地址空間

      網友投稿 826 2025-04-02

      @TOC

      零、前言

      本章主要講解學習進程地址空間的知識

      一、程序內存空間

      在學習C/C++中我們知道了程序內存的空間開辟以及內存分區的基本概念

      示圖:

      各分區作用:

      內核空間:用戶代碼無法讀寫

      命令行參數環境變量:儲存命令行參數環境變量

      棧區:存放運行函數而分配的局部變量、函數參數、返回數據、 返回地址等,棧區地址向下生長

      共享區:儲存文件映射,匿名映射,動態庫

      堆區:存放動態分配的變量,堆區地址向上生長

      數據段(初始化數據/未初始化數據區):存放全局變量、靜態數據

      代碼區:存放函數體(類成員函數和全局函數)的二進制代碼

      代碼驗證示例:

      #include #include int g_unval; int g_val=1; int main(int argc,char* argv[],char* env[])//命令行參數以及環境變量 { printf("code addr:%p\n",main);//代碼區 char* str="hello world"; printf("read only addr:%p\n",str);//只讀常量區:str是常量字符串的地址 printf("init addr:%p\n",&g_val);//初始化數據區 printf("uninit addr:%p\n",&g_unval);//未初始化數據區 int* p1=(int*)malloc(10); int* p2=(int*)malloc(10); printf("heap addr:%p\n",p1);//堆區 printf("heap addr:%p\n",p2);//堆區向上生長 printf("stack addr:%p\n",&str);//棧區 printf("stack addr:%p\n",&p1);//棧區向下生長 for(int i=0;argv[i];i++) printf("args addr:%p\n",argv[i]);//命令行參數區 for(int i=0;i<2;i++) printf("env addr:%p\n",env[i]);//環境變量區 return 0; }

      結果:

      二、進程地址空間

      1、引入及概念

      對于上述的程序地址空間,其實它的真實面貌為進程地址空間,對于進程地址空間本質上來說是一個虛擬地址空間,并非真實的物理空間

      示例:

      #include #include #include int main() { int i=10; pid_t id=fork();//創建子進程 if(id<0) { perror("fork fail\n"); return 1; } else if(id==0) { //child int cnt=0; while(1) { printf("I am child: i:%3d &i:%p pid:%d\n",i,&i,getpid()); sleep(1); if(cnt==3)//修改i的值 { i=100; } cnt++; } } else { //father while(1) { printf("I am father: i:%3d &i:%p pid:%d\n",i,&i,getpid()); sleep(1); } } return 0; }

      結果:

      分析:

      我們知道,父進程創建子進程時,子進程以父進程為模板構建進程,代碼父子共享,數據各有一份(誰進行寫入誰發生拷貝)

      而我們發現子進程數據發生修改時,子進程數據的地址和父進程的地址一樣,沒有發生改變

      對于變量內容不一樣,但地址值是一樣的,說明該地址絕對不是物理地址,因為是物理地址根本不會有這種事發生

      Linux進程地址空間

      2、進程地址空間

      概念:

      linux地址下,這種地址叫做 虛擬地址,我們在用C/C++語言所看到的地址,全部都是虛擬地址!物理地址,用戶一概看不到,由OS統一管理,OS必須負責將 虛擬地址 轉化成 物理地址

      進程地址空間本質是進程看待內存的方式,抽象出來的一個概念,對于每個進程來說,系統會給他們創建對應的PCB進程塊結構體,同時也相應的分配了對應的mm_struct進程地址空間(PCB中儲存了該進程對應的進程地址空間的地址),也就是每個進程都認為自己獨占內存資源

      對于進程來說,進程控制塊以及進程地址空間以及相應的資源,隨進程的創建而創建,隨進程的退出而回收

      進程地址空間的內容:

      進程地址空間是由0x00000000到0xffffffff的線性地址空間,按照刻度被劃分為各個區域,例如代碼區、堆區、棧區等

      在結構體mm_struct當中,便記錄了各個邊界刻度(對于堆向上增長以及棧向下增長實際就是改變mm_struct當中堆和棧的邊界刻度)

      示圖:

      注:在結構體mm_struct中各個刻度之間的每一個刻度都代表一個虛擬地址,這些虛擬地址通過頁表映射與物理內存建立聯系

      程序執行流程:

      程序運行,進程被加載到CPU上,系統在內核為進程創建PCB記錄進程屬性,分配進程空間地址,由頁表構建虛擬地址與物理地址的映射關系,程序查找或者修改數據會通過PCB找到對應的進程地址空間,再由進程地址空間上的虛擬地址由頁表找到物理空間上分配的數據

      示圖:

      對于父子進程變量地址相同數據不同:

      父進程創建子進程時,子進程以父進程為模板構建進程,代碼數據父子共享,當子進程進行修改數據時,由頁表發現該數據是父子進程共享的,所以系統會找到另一個物理空間進行拷貝數據,拷貝數據后再修改數據,達到數據各有一份互不干擾的目的

      注:這種在需要進行數據修改時再進行拷貝的技術稱為寫時拷貝

      示圖:

      3、相關問題

      為什么數據要進行寫時拷貝

      進程需要保證獨立性,多進程運行,需要獨享各種資源,多進程運行期間互不干擾,數據寫實拷貝讓子進程的修改不影響到父進程

      為什么不在創建子進程的時候就進行數據的拷貝

      子進程不一定會使用父進程的所有數據,并且在子進程不對數據進行寫入的情況下,沒有必要對數據進行拷貝,我們應該按需分配,在需要修改數據的時候再分配(延時分配),這樣可以高效的使用內存空間

      如果fork函數在子進程創建的同時即創建對應的數據結構還要拷貝數據的話,會降低fork的效率

      fork就是在向系統獲取資源,如果再拷貝的話,即獲取更多的資源,容易造成fork失敗

      代碼會不會進行寫時拷貝

      90%的情況下是不會的,但這并不代表代碼不能進行寫時拷貝,例如在進行進程替換的時候,則需要進行代碼的寫時拷貝

      為什么要有進程地址空間

      保護物理內存,不讓程序直接進行訪問物理地址,方便進行合法性校驗,控制以及管理了訪問的權限

      如果可以直接訪問,那么看到的地址就是物理地址,對于野指針,越界訪問等問題則不能進行很好的控制,不能保證程序的獨立性;當通過物理地址暴露,惡意程序通過物理地址進行讀取或者修改數據,無法保證信息和數據安全;控制以及管理了訪問的權限,以常量區不能的常屬性來說,當常量定義出來的時候不就是修改數據了么,但是再次修改時,通過頁表訪問時,頁表發現是常量區數據則拒絕修改的訪問,以此保護了數據的常屬性

      將內存管理與進程管理進行解耦

      如果直接使用物理地址,那么進程一創建就需要立即將數據寫到物理內存中,當進程退出就需要將數據立即釋放,也就是說內存的管理需要特別關注進程的狀態,這之間具有強相關性(耦合度高);具有進程地址空間后,進程管理只需管理PCB以及進程地址空間,而內存管理只需管理物理地址空間,也就是內存管理只需要通過智能指針知道內存區域那些是有效的哪些是無效的就能管理好內存,實現了進程管理與內存管理的解耦

      讓程序以同樣的方式看待代碼和數據

      可執行程序實際上也被分為了各個區域,例如初始化區、未初始化區等(便于程序編譯時進行查找和鏈接)。當該可執行程序運行起來時,操作系統則將對應的數據加載到對應內存當中即可,同時分區有利于執行的效率,大大提高了操作系統的工作效率。

      linux 任務調度

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:RFID技術在智能生產制造中的應用方案
      下一篇:制作表格斜邊框線怎么不能用(表格斜框線怎么弄)
      相關文章
      亚洲一级视频在线观看| 在线观看亚洲电影| 日韩国产精品亚洲а∨天堂免| 亚洲精品无码久久毛片波多野吉衣 | 亚洲日韩国产精品无码av| 色拍自拍亚洲综合图区| 亚洲成人激情在线| 亚洲伦理一区二区| 亚洲精品在线观看视频| 日木av无码专区亚洲av毛片| 亚洲视频在线观看免费| 99久久精品国产亚洲| 亚洲黄色网址大全| 亚洲精品电影天堂网| 亚洲乱码在线视频| 中文字幕在线日亚洲9| 亚洲一本到无码av中文字幕| 亚洲第一成年网站视频 | 国产av无码专区亚洲av桃花庵| 久久久青草青青亚洲国产免观 | 亚洲av永久无码精品网站| 亚洲国产精品不卡在线电影| 久久亚洲美女精品国产精品| 亚洲福利电影一区二区?| 亚洲不卡视频在线观看| 亚洲中字慕日产2021| 亚洲国产日韩a在线播放| 日韩精品电影一区亚洲| 亚洲一区精品伊人久久伊人| 亚洲色成人网站WWW永久| 亚洲AV无码一区二区乱子伦| 1区1区3区4区产品亚洲| 亚洲人成电影网站| 亚洲国产欧美日韩精品一区二区三区| 国产精品无码亚洲一区二区三区| 亚洲国模精品一区 | 亚洲无码一区二区三区 | 亚洲午夜电影一区二区三区| 亚洲AV成人一区二区三区在线看 | 亚洲黄网在线观看| 国产精品高清视亚洲一区二区|