? ? ? ? 本章將會介紹進程的一些概念:馮諾伊曼體系結構、進程是什么,怎么用、怎么表現得、進程空間地址、物理地址、虛擬地址、為什么存在進程空間地址、如何感性得去理解進程空間地址、環境變量是如何使用的。
目錄
1. 馮諾伊曼體系結構
? ? ? ? 1.1 是什么
? ? ? ? 1.2 結論
? ? ? ? 1.3 操作系統
? ? ? ? 1.4 搞管理的軟件 + 計算機的結構
? ? ? ? 1.5 總結
2. 進程的基本概念
? ? ? ? 2.1 什么是進程????????
? ? ? ? 2.2 為什么會有進程
? ? ? ? 2.3 見見進程
? ? ? ? 2.4 通過系統調用查看
? ? ? ? 2.5 fork()函數
3. 進程的狀態
? ? ? ? 3.1 為什么?
? ? ? ? 3.2 需要了解的三個狀態
? ? ? ? ? ? ? ?3.2.1 運行狀態
? ? ? ? ? ? ? ? 3.2.2 阻塞狀態
? ? ? ? ? ? ? ? 3.2.3 進程狀態的本質
? ? ? ? ? ? ? ? 3.2.4 掛起狀態
? ? ? ? 3.3 在Linux下的進程狀態
? ? ? ? ?????3.3.1 規定的幾種狀態
????????? ? ?3.3.2?進程的查看與孤兒進程
? ? ? ? ? ? ?3.3.3?僵尸進程
4.總結
1. 馮諾伊曼體系結構
? ? ? ? 1.1 是什么
? ? ? ? ? ?這個體系結構在我們計算機如筆記本、服務器,都是遵守這個體系結構。主要就是三部分 CPU 、 存儲器(里面存放的是物理地址)、IO設備。
? ? ? ? 1.2 結論
? ? ? ? ? 通過理解了這個結構,我們需要知道,我們的 CPU 在進行計算的時候不是直接與輸入輸出設備進行連接交互,是與存儲器進行交互。所有的外設,有數據的載入,只能載入到內存當中。
? ? ? ? 1.3 操作系統
? ? ? ? ?概念:任何計算機系統都包含一個基本的程序集合,稱為操作系統(OS)。簡單來說就是進行軟硬件結合的軟件。對上服務用戶(提供一個良好的執行環境),對下管理好各種硬件。
? ? ? ? 1.4 搞管理的軟件 + 計算機的結構
? ? ? ? 如何理解他是搞管理的軟件?,舉一個例子:在學校里面,我們見不到校長,但是校長會對我們進行管理,如何理解這個管理?就是雖然沒有見面,但是校長手里有我們的各種數據、例如:學號、成績、宿舍號、專業、掛了幾科,這些數據是校長進行決策的一個依據。校長就是根據這些數據來進行決策,如果是掛的科比較多了,就要警告,處理。所以我們就相當是各種硬件(被管理者),然后校長(管理者)就是 CPU 進行決策。他是怎么拿到數據的就是通過輔導員拿到數據。
? ? ? ? 那么管理者如何拿到數據,通過輔導員,在計算機系統中相當于驅動。
? ? ? ? 然后我們操作系統對于用戶想要進行的操作需要經過 shell(因為操作系統不相信我們用戶是安全的),提供的接口來調用系統內部的函數(系統調用接口,在 LINUX 就是 c 式的接口)。對內保護自己,對外提供服務。
? ? ? ? 1.5 總結
? ? ? ? 通過上面的例子,我可以推斷出。校長進行管理一個學生的時候需要對他的信息繼續描述變成一個結構體,然后將結構體通過鏈表或者是其他的數據結構連接到一起。所以對于同學的操作就變成對于結構體的操作。我們計算機也是需要這樣的。
? ? ? ? 所以!計算想要管理硬件需要兩步:1. 首先進行描述,將相關的內容變成(struct)結構體的形式存在 2.隨后進行組織,使用鏈表,其他高效的數據結構存放起來。
2. 進程的基本概念
? ? ? ? 2.1 什么是進程????????
? ? ? ? ? ? ? 進程是:一個運行起來(加載到內存)的程序/內存當中的程序。我們先來理解一下程序,就是寫在磁盤里的二進制程序。執行就要加載到內存當中。
? ? ? ? ? 一個cpu計算機可能許多的程序需要被執行,所以就需要進行描述 + 組織!繼續描述時需要通過 PCB(進程控制塊)struct task_struct{} 。在內存當中會對于沒有個程序提供一個進程控制塊。
? ? ? ? 通過上面的描述,我們對于進程的管理,轉化成對于鏈表的增刪查。進程 = 內核數據結構(表示當前進程的屬性,例如:掛起、阻塞、等待等狀態) + 進程對應的磁盤代碼以及數據(就是相關內容,拷貝到內存)。
? ? ? ? 2.2 為什么會有進程
? ? ? ? 一方面:需要進行管理,一個 cpu 只能執行一個進程,所以需要進行管理繼承。另外一方面
PCB 的作用就像一本進程的“身份檔案+進度卡,讓操作系統了解進程到達了程度了。
? ? ? ? 2.3 見見進程
? ? ? ? 簡單的進程,在Window里面。在Linux里面可以使用 ps ajx | grep '文件名'可以查看我已經打開的進程。
????????
在Linux 中我先書寫一個進程,然后再Xshell中顯示一下,如下圖所示:可以見簡單的看到有一個進程正在執行。
? ? ? ? 2.4 通過系統調用查看
? ? ? ? 可以使用兩個系統的函數,來查看當前進程的標識符 pid(當前進程進程) 與 ppid(父進程);??pid 很好理解,我們為什么需要有 ppid ,因為一個進程做的事情怎么樣了,肯定是需要有一個 leader 知道他干的怎么樣了,如何就需要給當前進程一個 ppid(父進程)。
? ? ? ? 2.5 fork()函數
? ? ? ? fork()是調用系統函數,實現創建一個子進程。他有兩個返回值一個,對應不同的進程有不同的返回值,例如:如果是子進程返回0,對于父進程返回他的子進程(為什么要這樣?因為父親就一個爹,所以不需要特別的說明,但是父進程有好幾個孩子,所以需要返回一個孩子的pid,說明是自己的大兒子,還是二兒子過來然我抱一下);
代碼表示的結果為:
#include <sys/types.h>
#include <unistd.h>
int main()
{// printf("pid: %d\n", getpid());// printf("ppid: %d\n", getppid());int ret = fork();if(ret == 0){printf("ret:%d\n", ret);printf("我是子進程,我的pid為:%d, ppid:%d\n",getpid(), getppid());}else{printf("ret:%d\n", ret);printf("我是父進程,我的 pid 為:%d, ppid為:%d\n",getpid(), getppid());}return 0;
}
到這里很多的同學,可能會有點疑惑為:為什么一個變量ret,會同時進行兩次打印,也就是為什么會有兩個結果。這個就跟進程有很大關系。
? ? ? ? 可以這么理解,我們的子進程,在創建的時候會進行寫時拷貝,開辟一模一樣一樣的空間,將父進程的部分內容拷貝過來,然后進行調用,通過管理PCB(struct結構體),經過頁表,就會單獨的進行子進程的代碼與數據。
3. 進程的狀態
? ? ? ? 3.1 為什么?
? ? ? ? 想要了解正在運行著的進程是什么意思?就要明白進程的狀態。我們為什么有要對進程有狀態的規定呢?
????????因為一個cpu只能進行一個進程其他的進程就需要進行等待的操作,所以其他的進程就要處于等待或者是其他的狀態。對于這個進程我們要能夠區分兩個概念,就是一個是操作系統哲學當中的進程狀態的概念,以及真正的在 Linux 當中使用的兩個概念。
? ? ? ? 3.2 需要了解的三個狀態
? ? ? ? ? ? ? ?3.2.1 運行狀態
? ? ? ? ? ? ? ? ? 一個 cpu 就有一個運行狀態,一個進程以 PCB 的形式存放在這個cpu的運行隊列里面。
? ? ? ? ? ? ? ? 3.2.2 阻塞狀態
? ? ? ? ? ? ? ? ? CPU的運行隊列中,在運行一個程序的時候不只是需要訪問 CPU 還需要訪問外設,但是外設又因為速度相比 CPU 比較慢所有需要在外設中重新開辟一個隊列,將接下來可能會運行的程序存放到這個隊列里面,這樣的操作就叫做堵塞狀態。
? ? ? ? ? ? ? ? 3.2.3 進程狀態的本質
? ? ? ? ? ? ? ? ? ? ?本質就是進程 PCB 結構體在不同的隊列之中。我們所說的進程是運行狀態不是進程正在運行,而是存放在 Running 這個結構體里面(這個結構體有head*指針,指向進程控制塊)。在其他的狀態也是這樣。
? ? ? ? ? ? ? ? 3.2.4 掛起狀態
????????????????由于內存的空間是有限的所以,遇到內存空間爆滿的時候就需要,將一些 PCB 對應的核心代碼放到存盤。等到需要的時候再將它取出(概括來說就是數據的換入、換出。)。????????
? ? ? ? 3.3 在Linux下的進程狀態
? ? ? ? ?????3.3.1 規定的幾種狀態
? ? ? ? ? ? ? ? 為了方便好看,這里就不再進行碼字,直接放上這張圖片。Linux 里面的進程相當于是對于操作系統里面進程的詳細化,實例化。
????????????????
? ? ? ? ? ? ? ? 還有的狀態為:+R,+S。有沒有 + 號的區別在于?有 + :表示前臺進程,輸入其他命令不會顯示的命令行上,無 + : 表示后臺進程,當進程在進行的時候,可以在命令行上使用其他的指令。(相當于有 + 之后變成了高級模式不能執行其他的指令,個人理解可能有錯🐱)
????????3.3.2?進程的查看與孤兒進程
? ? ? ? ? ? 我們想要查看進程可以使用?ps axj | grep。進行查看狀態。接下來我會寫一個程序來體現進程狀態。我寫一個持續打印的代碼,其中的狀態是 S+,阻塞狀態,為什么會這樣?因為使用外設打印的非常的慢,所以當 CPU 發出指令的時候外設的打印對列布滿了進程,每個進程都處于等待的狀態之中。
? ? ? ? ? ?我們先來感性的理解一下什么是孤兒進程:從字面意思可以看出,孤兒就是沒有父親,也就是沒有ppid,這里的沒有是指父親創建子進程后父進程被殺掉了,但是他的子進程還在運行中等待著子進程的回收。但是我們的進程是由 PID = 1(是由操作系統提供的) 的所以這個子進程會被 PID = 1 進程進行領養(使用 kill -9 殺死父進程)。從圖中可以看到父進程消失了,然后子進程的ppid 變成 1,被領養了。此時這個子進程就變成了孤兒進程。
??????????3.3.3?僵尸進程
? ? ? ? ? ? ? ? 是什么:感性 + 理性理解:僵尸進程就是父進程創建了一個子進程,然后子進程去執行操作,但是子進程退出了,但是父進程沒有回收子進程的信息,也就是 Z 狀態。好比:父母讓我們去買醬油,最后父母是需要知道我到底買沒買上,我最后的結果是什么,如果不告訴的化就會造成僵尸進程。解決為使用 wait(),來回收子進程,判斷子進程的信息,比如是正常退出,還是有異常退出,信息都存放在wait對應的參數列表里面。
? ? ? ? ? ? ? ? ?這個僵尸狀態的解決,到后面會進行講解,此處不進行過多描述。從圖片中可以看出進入了僵尸狀態。
4.總結
????????以上是對于進程狀態的回顧,下一章將會講解進程的優先級以及進程的切換🥵🥵🥵。這個文章用于我的學習記錄,如果是有其他的錯誤還請批評指正。如果對你有幫助還請給我點個贊👍👍👍。?????
????????
?????????
????????????????