進程(二)----環境變量、虛擬地址訪問物理空間、內存管理方式

進程優先級:一個進程對與CPU資源獲取的優先權

爲什麼要有優先級?(讓操作系統運行的更加良好)
交互式進程:直接與用戶進行交互的進程,(要求最好能夠更加有限的被CPU處理)。
批處理進程:在後臺默默做循環工作的進程。
環境變量:配置系統運行環境參數的變量。
環境變量優點使系統運行環境配置更加簡單靈活,可以通過設置環境變量給一個進程傳遞參數信息。(不用再去修改配置文件,重新加載配置文件,而是直接設置直接生效)

環境變量的操作

查看環境變量:env/set(查看所有變量,包含環境變量)/echo直接打印某一環境變量
設置環境變量:export
刪除環境變量:unset
環境變量是具有繼承性的:子進程也擁有父進程的環境變量
典型:PATH- - - - -系統命令程序的默認搜索路徑

代碼中環境變量的操作

  • main函數的第三個參數 int main(int argc,char *argv[ ],char *env[ ])…env保存環境變量
  • 通過一個全局變量eexern char **environ;…environ保存環境變量
  • char *getenv(const char *name);…通過環境變量名稱獲取一個指定環境變量的數據

變量的聲明:就是告訴編譯器,有這個變量的存在(但是這個變量不一定是我們自己定義的,這個聲明使用的變量通常是一個本文件之外的全局變量 a.c / b.c)
變量的定義:告訴編譯器這個變量是什麼樣子的
exetrn char **enciron;在本文件中聲明有這個變量/然而這個變量的具體內容實際上是外部的,是標準庫中存的。

程序地址空間

地址:對內存單元的編號
程序時不佔用內存的,運行起來的程序被加載到內存,纔會佔有內存。

  • 進程地址空間- - - -一個全局變量,在子進程中修改後,打印100,但父進程中依然打印1, 數據不同,表示肯定沒有使用同一塊內存空間(一塊內存空間不可能存儲兩個數據),父子進程打印的數據不同但是地址卻是相同的- - - - - 矛盾
  • 實際上進程中訪問的地址都是虛擬地址,而我們所說的程序地址空間實際上是一個進程的虛擬地址空間;
    虛擬一個地址空間:其實就是一個結構體 mm_struct;- - - - - 是一個對內存空間的描述- - - - -通過這個描述向進程虛擬出一個完整的、連續的內存空間;爲了能夠直接訪問物理內存
    size :示內存大小
    code_start/code_end:描述代碼段的起始與結束,通過這兩個信息就可以描述一塊空間。

進程直接訪問物理內存:

  • 1、進程中的代碼使用都是連續的地址,若直接使用連續的物理內存會造成內存的浪費;
  • 2、直接訪問物理內存會因爲缺乏內存訪問控制導致進程的不安全。
    在這裏插入圖片描述

如何通過虛擬地址訪問物理內存?

  • 操作系統爲進程創建mm_struct虛擬地址空間的同時,也創建了一個頁表用於映射虛擬地址與物理地址的關係;
  • 進程使用虛擬地址空間,通過頁表映射物理內存,可以實現進程中數據在物理內存上的離散式存儲,通過這種方式提高內存的利用率;
  • 在頁表中可以直接針對某個地址設置,這個地址的訪問權限(這個地址是隻讀的),通過這種方式實現內存訪問控制

爲什麼要使用虛擬地址空間?

  • 這些虛擬地址最終通過頁表映射到物理內存上實現數據離散式存儲(提高內存訪問率);
  • 在頁表中實現內存的訪問控制。

寫時拷貝技術:兩個一開始指向同一塊空間,等待發生改變的時候,再給子進程重新開闢空間,目的就是提高子進程創建效率。

操作系統通過虛擬地址空間,給每一個進程都虛擬的描述了一個完整的、獨立的地址空間,虛擬地址空間可以讓進程依然使用連續的虛擬地址,通過頁表映射之後,實現數據在物理內存上的離散式存儲,提高內存利用率。
每個進程都有一個虛擬地址空間,有一個頁表,並且通過頁表可以實現內存訪問控制,進一步提高進程的獨立性。

頁表的主要功能:映射虛擬地址與物理地址的關係/提供內存訪問控制。
頁表如何實現通過虛擬地址訪問物理地址?- - - - - MMU

內存管理方式

分頁式內存管理(提高內存利用率)

將物理內存進行分塊管理,通過頁表映射實現數據在物理內存上的離散式存儲。
分頁式內存管理的虛擬地址組成:頁號 + 頁內偏移
頁號:頁表中頁表項的編號
業內偏移:具體一個變量首地址相當於內存起始位置的偏移量

物理地址 = 物理內存塊 * 物理內存塊大小 + 虛擬地址中的頁內偏移
在這裏插入圖片描述

分段式內存管理(內存管理更加方便)

內存組成:段號 + 段內偏移
在這裏插入圖片描述

段頁式內存管理(集合了分頁式和分段式的優點)

每個分段都有一個頁表,通過地址中的段號,找到段表項,通過段表項中段內頁表起始位置找到自己的頁表,通過地址中的段內頁號,在這個頁表中找到頁表項,通過頁表項中的物理塊號 + 頁內偏移得到最終的物理地址
地址組成:段號 + 段內頁號 + 頁內偏移 + 段表 + 段內頁表 (在每一個分段內,又採用分頁式管理)

編譯器在編譯
編譯器在編譯程序的時候就會爲每一個指令以及數進行地址的分配(一個程序使用哪些地址,在編譯鏈接完成後就已經定下了),如果直接使用物理內存,哪個程序現在用了哪些地址,否則有可能造成衝突,都可以隨意使用連續地址信息,在加載到內存中農運行時計算一個總體偏移量。
在這裏插入圖片描述
直接訪問物理內存會存在一個問題:一個指針隨意賦值是一件可怕的事情,進程之間可以隨意通過地址訪問其他進程的空間以及數據,缺乏內存訪問控制

缺頁中斷

磁盤可以分爲:交換分區 和 文件系統分區。
交換分區:作爲交換內存使用。

當內存不夠的時候,這時候由於內存中並不是所有是數據都是活躍數據,操作系統會根據一定的算法,將某塊內存中數據保存到磁盤的交換分區中,騰出這塊內存加載新數據,但是每個進程的頁表中記錄了每一個虛擬地址對應的物理地址,如果這個虛擬頁面的物理內存中的數據被交換出去了,保存到交換分區,則將這個頁表項設置爲缺頁中斷。等待下次這個進程要訪問這個被交換出去的數據的時候(這個數據當前沒在內存中,而是保存在交換分區中),觸發缺頁中斷,重新從交換分區將數據交換回來。

LRU:一種內存置換算法- - - - -最久未使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章