主頁 > 軟體設計 > 【Linux】行程理解

【Linux】行程理解

2021-12-08 09:30:20 軟體設計

目錄

  • 一、馮諾依曼體系
  • 二、作業系統概念
  • 三、行程
    • 3.1 行程概念
    • 3.2 描述行程-PCB
    • 3.3 行程狀態
  • 四、行程地址空間

一、馮諾依曼體系

我們先來看一下日常生活中,我們所用的電腦或者公司用的服務器都遵守馮諾依曼體系
在這里插入圖片描述
由五種組成,分別是輸入設備,存盤器,運算器,控制器和輸出設備

輸入單元:滑鼠,鍵盤,掃描儀,寫板,網卡,磁盤,話筒等
存盤器:也就是物理記憶體,后續講行程地址會詳細講
運算器和控制器:都屬于CPU,運算器在CPU中會做兩件事一是執行算術,二是執行邏輯
輸出單元:顯示幕,網卡,磁盤,音響

輸入和輸出設備統稱為外設,其次CPU并不和外設打交道,同樣的外設只和記憶體打交到

程序:輸入單元輸入的是資料,資料寫入存盤器進行處理(運算器和控制器)然后再傳出輸出設備,因此馮諾依曼規定了硬體層面上的資料流向

那么從馮諾依曼體系的角度來解釋一道題:
小明在廣東給遠在安徽的小紅發了一句在嗎?那么請問發送了這個“在嗎?”資訊經過了哪些步驟?
ans:輸入在嗎?通過輸入設備,然后存盤到存盤器,qq軟體運行的時候也跑在存盤器上,通過加密運算等程序再寫回到存盤器然后qq再把資料重繪出去,到輸出設備,此時的輸出設備叫網卡,通過網路朋友家接收資料的輸入設備此時是網卡,不是鍵盤然后網卡的資料首先也會貫道記憶體里,qq在記憶體中獲得訊息,經過CPU運算解包再寫到存盤器里,然后存盤器再定時的刷到顯示幕上,朋友最終收到了訊息

二、作業系統概念

作業系統是進行軟硬體資源管理的軟體,管理硬體用struct結構體進行描述,用鏈表或其他高效資料結構進行組織,作業系統包括以下:

  1. 內核(行程管理,記憶體管理,檔案管理,驅動管理)
  2. 其他程式(例如函式庫,shell程式等)

為什么會有有作業系統?
3. 可以減少用戶使用計算機的成本
4. 對下管理好所有的軟硬體,對上對用戶提供一個穩定高效的運行環境

三、行程

3.1 行程概念

那么什么是行程?
行程 = 你的程式 + 內核申請的資料結構(PCB),程式加載到記憶體里,作業系統為此創建PCB結構體變數然后里面填上該行程的屬性資訊最終完成行程創建

舉個例子,當我們啟動一個google瀏覽器,或者進行下載等,程式一旦運行就是行程,
行程是資源分配的最小單位,且每個行程擁有獨立的地址空間

那么問題來了!!
如果我們開啟了幾十個行程呢?對于作業系統來說就必須要進行管理
正如上面所提到的我們對于每個行程都遵守先描述再組織的原則,先描述就是為每個行程創建一個行程控制塊PCB,行程資訊被放在行程控制塊的資料結構中,然后一個個的行程由鏈表或其他高效資料結構進行組織

3.2 描述行程-PCB

那么我們就詳細了解一下PCB,可以理解為行程屬性的集合,就好像在自然界中我們看到一個動物會通過它的特征進行描述組織從而精準的判斷,
在Linux作業系統下的描述行程結構體叫做task_struct
task_struct是linux內核中的一種資料結構,被裝在到記憶體里并且包含著對應行程的資訊

  1. 標示符: 描述本行程的唯一標示符,用來區別其他行程,也就是我們在Linux下看到的PID
    我們可以grep一個行程看到
    在這里插入圖片描述
  2. 狀態: 任務狀態,退出代碼,退出信號等,
  3. 優先級: 相對于其他行程的優先級,
  4. 程式計數器: 程式中即將被執行的下一條指令的地址,
  5. 記憶體指標: 包括程式代碼和行程相關資料的指標,還有和其他行程共享的記憶體塊的指標
  6. 背景關系資料: 行程執行時處理器的暫存器中的資料[休學例子,要加圖CPU,暫存器],
  7. I/O狀態資訊: 包括顯示的I/O請求,分配給行程的I/O設備和被行程使用的檔案串列,
  8. 記賬資訊: 可能包括處理器時間總和,使用的時鐘數總和,時間限制,記賬號等

注意:行程放在CPU上后,不是一直在運行知道行程結束的

一般行程讓出CPU有兩種情況

  1. 來了一個優先級更高的行程
  2. 時間片到了

并發和并行的概念:
單CPU:跑起來多個行程,通過行程快速切換的方式,有個時間片,在一段時間內給行程運行一段固定的時間片時間,然后給下一個,從而實作并發
多核CPU:任何時刻,允許多個行程同時執行,并行

行程間切換:
最重要的就是保存背景關系,把臨時資料保存在PCB中,讓出給其他的行程
如果有4個行程被切,是出于運行狀態的,所以我們的作業系統會給每個CPU形成對應的 運行佇列,通過運行佇列把所有的PCB鏈接起來(也是用全域的鏈表連接起來,因為PCB里面包含了大量的指標,和檔案等其他事務關聯),這些佇列是CPU所系結的運行佇列,CPU拿任務時就從這個佇列中去拿任務,狀態都為 R 狀態

在這里插入圖片描述

作業系統進行行程調度,CPU執行
總結:

  1. 我們的行程進行切換時,因為某些原因如時間片到了,或者遇到了一個優先級更高的行程,當前正在運行的行程需要保存背景關系資訊,然后讓出CPU,另一個新到來的行程需要將自己的資料放入暫存器中,當被切走的行程回來時,也需要首先做恢復作業,這就叫背景關系的保存與恢復
  2. 每一個行程都隸屬于某一個運行佇列,CPU直接從佇列中調度

代碼中用fork進行理解
在這里插入圖片描述
在這里插入圖片描述

  1. 程式員角度:父子共享用戶代碼,而用戶資料各自私有一份,其中父子共享用戶代碼是只讀的,不可修改和寫入, 為什么要私有?作業系統中,所有行程具有獨立性,如一個app掛掉而不影響另外一個行程的運行, 所以私有一份,不讓行程相互干擾所以是只讀的不能修改
  2. 內核角度:fork后,系統多了一個行程,創建子行程,通常以父行程為模版其中子行程默認使用的是父行程的代碼和資料(寫時拷貝)

為什么給子行程回傳的是0,父行程回傳子行程的pid?
兒子 -> 唯一父親 , 因此兒子找父親是特別簡單的,是0
父親 -> 多個子女 ,而一個父親找特定的兒子是特別難的,所以要用不同ID區分

3.3 行程狀態

在這里插入圖片描述
通過task state array定義可以看出一共有七種狀態
在這里插入圖片描述

  1. R狀態可以時正在運行,但是R狀態有時候也并不代表是在CPU上面運行,行程在佇列中等待被調度時,或者說行程準備就緒時也是R狀態
    在這里插入圖片描述
  2. S狀態,也叫淺度休眠,對外部事件可以做出反應,如ctrl+c 可以停止休眠
  3. D狀態,也叫深度休眠,不可以被kill掉,即便是作業系統通常在訪問磁盤進行資料拷貝的關鍵步驟上是需要將行程設定為Deep sleep的,只能等待D狀態行程自動醒來,或是關機重啟
  4. 小T狀態,是一種等待狀態
    在這里插入圖片描述
    在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
-18讓行程又開始跑起來

  1. 大T狀態,tracing stop用于打斷點,行程就不跑了
    在這里插入圖片描述

  2. Z狀態,僵尸狀態
    行程退出時會將自己退出的相關資訊寫入行程的PCB中,供OS或者父行程來進行讀取,其中我們把一個行程退出了但還沒有被讀取的時間點,我們稱該行程來僵尸狀態,
    注意:這里Z狀態一直不退出,PCB要一直維護,如果父行程創建了很多子行程就是不會收,就造成了記憶體資源浪費,因為資料結構物件本身就要占用記憶體,換言之造成記憶體泄漏

  3. X狀態,行程結束
    讀取成功后,該行程才算真正死亡!為X狀態

舉個僵尸狀態的例子:
在這里插入圖片描述
在這里插入圖片描述
當子行程執行完自己的事情后退出了,父行程還在S狀態,但父行程不回收子行程,這時候子行程都會處于僵尸狀態

僵尸行程本質上是為了維護一種臨時狀態,讓我們父行程對子行程進行讀取,進而回收資源,以及釋放對應行程所占的資源

??注意:Z狀態已經掛掉,是不能被Kill掉的,plus 深度休眠狀態也是不能kill掉的

  1. 孤兒行程
    先來看一組代碼
    在這里插入圖片描述下面的代碼父行程首先fork后,父行程先退出了,那么就不會去讀取子行程的回傳代碼了
    那么這個老爹退出了之后,子行程還在S狀態,需要被領養,也就是被PPID 為1作業系統給領養
    那么這個被領養的行程就叫孤兒行程,非常的形象生動吧!
    在這里插入圖片描述
    我們給下命令> top
    查看 一下1號行程
    在這里插入圖片描述

四、行程地址空間

前面的都是開胃菜,這里才是重頭戲!
首先看一幅圖在這里插入圖片描述
行程地址空間從下到上為低地址到高地址

printf("Lowest area: code Address : %p 		\n",  main); //main是函式,一定是屬于代碼的一部分,所以可以充當代碼段
const char* p = "I'm in const or you can call me static area"; //堆疊區定義一個p變數,p變數保存的是常量區的字串
printf("Read Only 		  : %p 		\n", p); //p就是保存該常量的起始地址, 如果是static int,也在這里(生命周期全域)
printf("global initAlready 	  : %p		\n", &g_InitAlready);
printf("global Uninitalized	  : %p		\n", &g_unInit);
char *q = (char*)malloc(10);
printf("Heap Addr		  : %p		\n", q); //注意是q,而不是&q,如果是&q則是保持在堆疊區的變數名地址,而不是q內容
printf("Stack Addr p		  : %p		\n", &p); //堆疊區向下增長,p先入堆疊,因此地址會比q的要大	
printf("Stack Addr q		  : %p		\n", &q);
	
printf("args Addr		  : %p		\n", argv[0]);
printf("argv Addr		  : %p		\n", argv[argc-1]); //帶一些選項就不一樣了
printf("Env Addr		  : %p		\n", env[0]);

在這里插入圖片描述
上圖論證了各個區域所存放的地址,從代碼段到環境變數區域由低向高走

行程地址空間,不是記憶體!是虛擬出來的,后面會講到到每一個行程都會認為自己有一塊這么大的空間,
行程地址空間,會在行程的整個生命周期一直存在,直到行程退出! 這就是為什么定義的全域變數在為初始化,初始化,靜態區一直存在了

我們可以論證這樣一個觀念:
假設記憶體是4GB,創建出來的每個行程都會認為自己有一塊這么大的空間


val = 0的情況
如果一個行程創建了一個child后sleep 3秒鐘,child先跑,對val進行修改后為10,父親再讀取這個val,child列印出來的val=10,而父val=0,但是發現他們的地址盡然一樣!,這也從側面論證了我們看到的不是實實在在的物理地址,而行程地址空間本質上就是一種虛擬地址,他們的值可以不一樣是因為行程間是相互獨立的,代碼雖然是共享,資料是各自私有的,當發生寫的動作時就是寫時拷貝

行程地址空間的資料結構:
在這里插入圖片描述
地址空間是在行程和物理空間之間的一個軟體層,通過mm_struct來模擬 讓作業系統給每個行程畫大餅,讓每個行程都認為自己有整個地址,或者說物理記憶體,這樣我們的每個行程就可以根據自己的地址空間來劃分自己的代碼

地址空間和物理記憶體之間的關系:

  1. 把行程的代碼和資料加載到記憶體中,并給行程創建行程地址空間
  2. 給每個行程創建一個頁表結構,頁表構建的就是從行程地址空間出來的虛擬地址到物理地址當中的映射

因此我們就可以說父子行程列印出來的地址可以是完全一樣,而值不同

頁表有權利去控制某段資料有沒有權限寫進物理記憶體,也就是說,地址空間中的字符常量區和代碼區給到頁表是只讀權限的,我們創建的一個指標變數p,在堆疊中保存,指向的資料在常量區,不能進行修改,報segmentaltion fault

那么問題來了:

為什么不把輸入設備的值直接放入物理地址不就完事了嗎?還每個行程額外虛擬出來一塊地址空間干嘛呢?
如果直接訪問物理記憶體,行程一多就有可能發生指標越界,那么行程的獨立性就無法得到保證,因為物理記憶體暴露,可能有惡意程式直接對記憶體資料行程篡改或者讀取了

有了地址空間的好處:

  1. 保護物理記憶體,不收到任何行程內的地址的直接訪問,方便進行合法性檢測
  2. 將記憶體管理和行程管理進行解構( 比如創建行程,只需在頁表中向系統申請記憶體,當行程釋放只需通過頁表釋放記憶體(記憶體管理只需知道哪些記憶體區域(Page頁表)是無效的,哪些是有效的),但如果沒有頁表行程和物理記憶體之間是強耦合的
  3. 讓每個行程,以同樣的方式,來看待代碼和資料,想象一下當每個可執行程式都已經在執行前被劃分好了一塊塊區域,通過頁表,物理地址可以進行高效訪問

創作不易,如果文章對你幫助的話,點贊三連哦:)

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/375955.html

標籤:其他

上一篇:《演算法零基礎100講》(第48講) 位運算 (左移)

下一篇:除了微服務,我們還有其他選擇嗎?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more