Linux-地址空間

目錄

1.介紹

2.理解

3.Linux早期的內核調度隊列


1.介紹

這是32位的程序空間地址圖:

為了更好地理解這段圖,我們來寫一段代碼編譯運行:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int g_val=100;int main()
{pid_t id = fork();int cnt=3;if(id == 0){while(1){printf("I am child, pid=%d, ppid=%d,g_val=%d &g_val=%p\n", getpid(), getppid(),g_val,&g_val);sleep(2);cnt--;if(cnt==0){g_val=500;printf("I am child,change pid=%d->%d\n", 100,500);}}}else {while(1){printf("I am father, pid=%d, ppid=%d,g_val=%d &g_val=%p\n", getpid(), getppid(),g_val,&g_val);sleep(2);}}return 0;
}

我們可以看見子進程修改 g_val 的地址后,父進程的地址和子進程的地址是一模一樣的,一個地址為什么會有兩個不同的值?

答案是這是個虛擬地址,不是物理內存地址,我們在用C/C++語言所看到的地址,全部都是虛擬地址!物理地址,用戶一概看不到,由OS統一管理,下面我們從操作系統來理解地址空間

地址空間的本質是內核中的結構體對象。

未寫時拷貝(初始共享)

父進程 fork 創建子進程,虛擬地址空間、頁表 “邏輯復制” :父子進程虛擬地址(如 g_val 地址 0x56ab5ceac010 )一致,頁表均映射到物理內存同一塊數據頁(g_val = 100 )。此時代碼、數據物理頁共享,不實際拷貝內存,快速創建進程,節省空間。

寫時拷貝(觸發拷貝)

當子 / 父進程嘗試修改共享數據(如子進程改 g_val值?),操作系統檢測到寫操作:
為寫操作進程(如子進程)新分配物理頁;
把原共享物理頁數據(100 )拷貝到新頁;
更新寫操作進程頁表,使其指向新物理頁(此時子進程 g_val 500 )。父進程頁表不變,仍訪問原物理頁(g_val 保持 100 ),實現 “寫時才真正拷貝內存”,避免冗余開銷
核心邏輯:讀共享,寫拷貝,平衡進程創建效率與數據獨立性 。

2.理解

1.地址空間的本質是 struct 里面的一個結構體,內部很多屬性都是表示 start end 的范圍。?

2.虛擬地址無序變為有序,讓進程從統一的角度看待物理內存以及自己運行的各個區域。

3.進程管理模塊內存管理模塊相互解耦。

在計算機系統(尤其是操作系統、分布式框架)中,進程管理模塊(負責進程的生命周期管理、調度、狀態維護、權限控制等)與內存管理模塊(負責內存分配、回收、地址映射、虛擬內存管理等)是核心功能模塊。

二者的 “相互解耦” 是指通過設計隔離模塊間的直接依賴,使它們能獨立完成各自功能,僅通過標準化接口協作,從而提升系統的可維護性、擴展性和容錯性。

虛擬地址頁表是實現兩者解耦的核心機制之一

4.攔截非法請求

虛擬地址頁表通過地址合法性驗證權限檢查進程地址空間隔離,構建了一層硬件級別的保護機制。它能有效攔截非法的內存訪問請求(如越界、權限違規、訪問未分配內存等),防止物理內存被錯誤或惡意操作破壞,是操作系統保障內存安全的核心手段之一。

之前我們介紹 Linux 進程的時候講過一段代碼

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork failed");return 1;} else if (pid == 0) {while(1){printf("Child process: ID=%d PID = %d, PPID = %d\n", pid , getpid(), getppid());sleep(2);}} else {while(1){printf("Parent process: ID=%d PID = %d, Child PID = %d\n",pid , getpid(), pid);sleep(2);}}return 0;
}

fork() 對子進程進行了寫時拷貝,所以才返回了兩個不同的值。

3.Linux早期的內核調度隊列

一個 CPU 擁有一個 runqueue

  • 如果有多個 CPU 就要考慮進程個數的負載均衡問題

運行隊列優先級

queue[140]

之前我們介紹進程優先級的時候,我們介紹過進程默認優先級是 80,nice的范圍為 [20,-19]。

進程隊列的優先級為:

  • 普通優先級:100~139
  • 實時優先級:0~99

我們的進程值+40就能建立和進程隊列的映射

位圖:

long bitmap[ 5 ]

我們的隊列優先級有140個,要是一個個逐一檢測,會增加時間。

bitmap就是為了節約時間的 long bitmap[5]?有 32*5=160 足夠包含這么多的優先級,我們只要看位圖的數字就能找到哪個優先級還存在進程。

這就是大 O (1) 調度算法大 O (1) 調度算法指的是無論輸入規模(比如進程數量、任務數量等)如何變化,算法執行所需的時間保持恒定,不隨輸入規模的增大而增加。

活動隊列(Active Queue)(只出不進)

  • 作用:用于存放時間片尚未耗盡的進程,這些進程會依據優先級進行組織,系統優先調度優先級高的進程,以此保障系統能夠高效響應任務需求。
  • 調度邏輯:利用 bitmap 快速查找出優先級最高的非空隊列,然后選取該隊列的隊首進程執行。不管系統中進程的總數是多少,查找和調度進程所花費的時間始終固定,其時間復雜度為?O(1)?,確保了調度過程高效、穩定。

過期隊列(Expired Queue)(只進不出)

  • 作用:用來存放時間片已經耗盡的進程,它的結構和活動隊列完全一樣,可看作是進程時間片管理的 “過渡區域”。
  • 特點:當活動隊列中的進程把自身時間片用完后,就會被轉移到過期隊列中。而當活動隊列為空(意味著所有進程的時間片都已耗盡 )時,系統會交換 active 和? expired?指針,此時過期隊列就轉變為新的活動隊列,同時重新計算該隊列中進程的時間片,讓這些進程能夠再次參與到系統調度中,以此實現 “批次輪換” 的調度機制,保障進程獲取調度的公平性。

active 指針和 expired 指針

  • active 指針:始終指向當前可供調度使用的?活動隊列,系統會從該隊列里選取進程來執行任務。
  • expired 指針:始終指向?過期隊列,用于暫時存放那些時間片已經耗盡的進程。
  • 核心機制:在系統運行過程中,活動隊列里的進程會因為時間片不斷消耗而逐漸減少,與之相對,過期隊列里的進程數量會相應增多。當活動隊列為空時,交換這兩個指針,過期隊列就 “變身” 為新的活動隊列,原本過期隊列中的進程會重新獲得時間片,繼續參與系統調度。這種方式無需實際去搬運進程,就能瞬間重置調度資源池,保障調度持續高效地進行。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/918936.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/918936.shtml
英文地址,請注明出處:http://en.pswp.cn/news/918936.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

**標題:發散創新之力,探索隱私計算的未來**隱私計算,作為當下數字化時代的熱門話題,正受

標題&#xff1a;發散創新之力&#xff0c;探索隱私計算的未來 隱私計算&#xff0c;作為當下數字化時代的熱門話題&#xff0c;正受到越來越多開發者和從業者的關注。本文將帶您走進隱私計算的奇妙世界&#xff0c;探討其背后的技術原理、應用場景以及發展趨勢。 一、隱私計算…

線程P5 | 單例模式[線程安全版]~懶漢 + 餓漢

什么是單例模式&#xff1f;在我們正式講解單例模式之前&#xff0c;沒有了解過的小伙伴可能會有疑問...到底啥叫單例模式&#xff1f;&#xff1f;其實單例模式呢&#xff0c;是我們設計模式中的一種&#xff0c;所謂的設計模式&#xff0c;你可以把它理解為一個模板&#xff…

kubernetes中數據存儲etcd

etcd 在 Kubernetes 中的角色核心定位&#xff1a;Kubernetes 的 唯一持久化數據存儲&#xff08;一致性數據庫&#xff09;。職責&#xff1a; 保存整個集群的期望狀態&#xff08;desired state&#xff09;&#xff0c;包括節點信息、Pod 清單、Service 定義、ConfigMap、Se…

Linux crontab定時任務

參考資料 【図解】cronの仕組み定時任務 - crontab解決ubuntu下定時任務不執行問題crontab環境變量問題&#x1f4a5;Linux定時任務功能詳解&#xff1a;crontab與at命令應用指南 目錄一. 環境準備1.1 wsl開啟systemd1.2 開啟cron日志二. cron服務管理相關命令2.1 service 的方…

企業頻繁收到軟件律師函?如何徹底解決這一難題

1. 引言&#xff1a;律師函頻發&#xff0c;已成信息化管理的“隱形雷區”在工業制造、芯片、航空航天、船舶制造、醫療器械等高要求行業&#xff0c;軟件不僅是研發與生產的關鍵工具&#xff0c;更是企業數據與知識產權安全的“底座”。然而&#xff0c;不少企業卻在日常運營中…

在 macOS 上順利安裝 lapsolver

一、什么是 lapsolver&#xff1f; lapsolver 是一個用于求解線性分配問題&#xff08;Linear Assignment Problem, LAP&#xff09; 的 Python 庫。線性分配問題是運籌學中的經典問題&#xff0c;核心是在兩個集合&#xff08;如“工人”與“任務”&#xff09;之間找到一組最…

宋紅康 JVM 筆記 Day02|JVM的架構模型、生命周期、發展歷程

一、今日視頻區間 P13-P25 二、一句話總結 JVM的架構模型&#xff1b;JVM的生命周期&#xff1b;JVM發展歷程&#xff1b; 三、關鍵圖/命令 3.1 JVM的架構模型Java程序對.class字節碼文件進行反編譯操作&#xff1a;在idea中先運行需要反編譯的代碼&#xff0c;找到對應的字節碼…

Linux新手上路 | 在Ubuntu上Pluma文本編輯器的安裝與基本使用

Linux新手上路 | 在Ubuntu上Pluma文本編輯器的安裝與基本使用一、Pluma工具介紹1.1 Pluma 工具概述1.2 主要功能1.3 適用場景二、安裝Pluma2.1 安裝方法2.2 啟動Pluma工具三、漢化方法3.1 安裝漢化包3.2 設置系統語言3.3 重新打開Pluma四、基本使用方法4.1 編寫文本內容4.2 關鍵…

React 揭秘:從新手到高手的進階之路

目錄 React&#xff1a;前端開發新寵? React 初相識? 什么是 React? React 的核心特性? 1.組件化開發 2.虛擬 DOM 與 Diff 算法 單向數據流 搭建 React 開發環境 環境準備? 創建 React 項目 項目結構解析 React 基礎語法與核心概念 JSX 語法? 基本語法規則…

八股文小記 Servlet 過濾器-Spring MVC 攔截器-Spring AOP 攔截器區別

您對執行機制的洞察非常準確&#xff01;讓我們深入分析這三種組件的調用機制及其與 AOP 節點的關系&#xff1a; 一、執行機制的本質區別組件調用機制實現原理Servlet 過濾器遞歸調用通過 FilterChain.doFilter() 顯式遞歸調用下一個節點Spring MVC 攔截器遍歷調用由 HandlerE…

qml 實現數值鍵盤

import QtQuick 2.0import QtQuick.Layouts 1.12 import"../pad" // PasswordKeyboard.qml import QtQuick 2.12ColumnLayout {id: keyboardspacing: 8// 鍵盤標題Text {text: "安全輸入"font.pixelSize: 16color: "#666"Layout.alignment: Qt.A…

PID控制算法

文章目錄引言一、基本原理1.1.簡介1.2.開環與閉環1.3.PID 的公式1.3.1.比例項&#xff08;Proportional&#xff09;1.3.2.積分項&#xff08;Integral&#xff09;1.3.3.微分項&#xff08;Differential&#xff09;1.4.連續形式與離散形式的 PID 公式1.4.1.連續形式1.4.2.離散…

MyBatis 動態數據源切換在 Spring Boot 環境下的實現方案

第一章 需求背景與技術選型1.1 多數據源場景概述在大型企業級應用中&#xff0c;單一數據庫往往無法滿足高并發和多業務線的需求&#xff0c;因此需要引入 多數據源 的架構設計。常見的多數據源場景包括&#xff1a;讀寫分離、多租戶、分庫分表以及數據源負載均衡等。讀寫分離&…

PCA降維理論詳解

文章目錄一、什么是PCA&#xff1f;二、為什么需要降維&#xff1f;三、PCA的數學原理與詳細推導視角一&#xff1a;最大化投影方差&#xff08;Maximizing Variance&#xff09;視角二&#xff1a;最小化重構誤差&#xff08;Minimizing Reconstruction Error&#xff09;四、…

Android RxJava變換操作符詳解

RxJava作為響應式編程在Android開發中的利器&#xff0c;其強大的變換操作符能夠幫助我們優雅地處理數據流。本文將深入講解RxJava中最常用的變換操作符及其實際應用場景。一、RxJava變換操作符概述變換操作符(Transformation Operators)用于對Observable發射的數據序列進行變換…

開源數據發現平臺:Amundsen 快速上手指南

Amundsen 是一個數據發現和元數據引擎&#xff0c;旨在提高數據分析師、數據科學家和工程師與數據交互時的生產力。目前&#xff0c;它通過索引數據資源&#xff08;表格、儀表板、數據流等&#xff09;并基于使用模式&#xff08;例如&#xff0c;查詢頻率高的表格會優先于查詢…

【密碼學實戰】國密SM2算法介紹及加解密/簽名代碼實現示例

引言 在信息安全領域&#xff0c;密碼算法是數據保護的核心基石。2010 年&#xff0c;中國國家密碼管理局發布了 SM2 橢圓曲線公鑰密碼算法&#xff0c;作為國產密碼標準的核心成員&#xff0c;它憑借高效安全的特性&#xff0c;逐步替代 RSA 等國際算法&#xff0c;廣泛應用于…

QT開發中如何加載第三方dll文件

文章目錄&#x1f527; 一、隱式加載&#xff08;靜態鏈接&#xff09;操作步驟&#xff1a;?? 二、顯式加載&#xff08;動態鏈接&#xff0c;推薦使用QLibrary&#xff09;操作步驟&#xff1a;&#x1f4bb; 三、直接調用Windows API&#xff08;僅Windows&#xff09;??…

后端學習資料 持續更新中

數據庫&#xff1a; 該網址包含&#xff1a;圖解MySql&#xff0c; 看明白誰也問不倒你~ 圖解計算機網絡、操作系統、計算機組成、MySQL、Redis&#xff0c;讓天下沒有難懂的八股文&#xff01;https://xiaolincoding.com/

《嵌入式Linux應用編程(六):并發編程基礎:多進程exec函數族及多線程基礎》

一、exec函數族在一個進程里面執行另一個文件本質&#xff1a;將文本區的指令代碼替換成exec要執行的指令#include <unistd.h>參數&#xff1a;path:要執行的可執行文件的路徑和名稱arg:執行該可執行文件時需要傳遞的參數NULL&#xff1a;參數傳遞結束標志 返回值&#x…