久综合色-久综合网-玖草影视-玖草资源在线-亚洲黄色片子-亚洲黄色片在线观看

Hello! 歡迎來到小浪云!


【Linux】從硬件到軟件了解進程


一、馮諾依曼體系結構

我們常見的計算機結構,包括哈佛結構和馮諾依曼體系結構,我們日常使用的計算機就是基于馮諾依曼體系結構的。下圖展示了這種體系的直觀圖。

【Linux】從硬件到軟件了解進程 在這里的存儲器指的是內存,如果不考慮緩存的情況,CPU只能對內存進行讀寫,不能直接訪問輸入輸出設備。輸入輸出設備要輸入或輸出數據,必須先寫入內存或從內存中讀取。也就是說,盡管CPU是中央處理器,但在馮諾依曼結構中,內存才是核心部件,所有數據必須先經過內存,然后再流向其他地方。

馮諾依曼體系結構是計算機普及的重大突破。我們知道計算機的存儲速度如下圖所示,寄存器是最快的存儲設備,也是最昂貴的,而機械硬盤(HDD)是最慢的存儲設備,也是最便宜的。如果沒有馮諾依曼結構,我們的計算機要么便宜但速度慢,要么昂貴但速度快。馮諾依曼結構的原理是在CPU進行計算時,內存已經接收并存儲了外部輸入設備輸入的數據。CPU計算完成后,將結果取出并發送到輸出設備,然后將新的輸入數據傳遞給CPU進行計算。這樣,低速的輸入輸出設備、中速的內存和高速的CPU有機結合,形成了現代計算機的雛形。

【Linux】從硬件到軟件了解進程二、操作系統任何計算機系統都包含一個基本的程序集合,這個集合被稱為操作系統。我們前面提到過,操作系統由操作系統內核和命令行解釋器(shell)組成。設計操作系統的目的是更好地與硬件交互、管理軟件資源,并為應用程序提供一個良好的執行環境。

【Linux】從硬件到軟件了解進程 如上圖所示,我們可以清楚地看到用戶和系統軟件之間的交互。我們不能直接調用操作系統,操作系統就像一只小蝸牛,它縮在殼里通過觸角與你交流。除了觸角,你無法觸及蝸牛的身體。這里的觸角就是系統調用接口。操作系統也有殼,除了通過系統調用接口,其他方式都無法間接使用操作系統。由于系統調用在使用上比較基礎,對用戶的要求較高,因此開發者對部分系統調用進行了適度封裝,形成了庫。有了這些庫,程序員就可以更好地開發軟件,然后這些軟件再被普通用戶使用。

對于硬件部分和系統軟件部分的交互,我們前面提到過,操作系統負責管理。對于程序員來說,管理可以通過計算機語言中的數據結構來表示。大家不妨想想,我們在日常生活中遇到的管理問題,是不是都可以轉化為數據結構的方式來解決?我是一個學生,我舉一個關于學生管理的例子:一個學校有十個學院,每個學院有一位院長和一百位學生,假設我們的學校就這么簡單,沒有其他類似輔導員這樣的職位。校長不直接管理學生,而是通過院長來管理。院長需要親力親為,親自管理這些學生。學生的屬性各不相同,但學生屬性的類型是相同的,他們都有名字、性別、年齡、家庭住址。我們可以將學生這個群體定義為一個struct結構體,然后不同的學生填寫不同的數值,再按照學號前后以單鏈表的方式連接起來,這樣就把每個學院的學生連接起來了。對學生的管理就是對鏈表的增刪查改。校長想要管理某個學生時,可以通過院長執行。這里的校長就是操作系統,院長就是驅動程序,而學生就是硬件資源。一個事件可以拆分為決策和執行,操作系統負責決策,驅動程序負責執行。我們剛才的例子對于學生也就是硬件資源,就是一個先描述再組織的過程,先將個體描述出來,再將個體組織起來。

三、操作系統進程管理1、概念進程是正在執行的程序的實例,是操作系統進行資源分配和調度的基本單位。它包含了程序計數器、寄存器、內存空間、打開的文件描述符等運行上下文信息,這些信息共同構成了進程執行的環境。

進程是正在執行的程序的實例,程序本身只是存儲在磁盤等介質上的一組指令和數據的集合,是靜態的。只有當程序被加載到內存中,并由操作系統為其分配資源、創建相應的數據結構來管理其執行時,它才成為一個進程,即變成了一個動態的執行實體。

進程是操作系統進行資源分配的基本單位,操作系統需要為每個進程分配獨立的資源,包括但不限于內存空間、CPU時間、文件描述符、網絡端口等。每個進程都有自己獨立的地址空間,進程在自己的地址空間內可以自由地訪問和操作數據,而不會干擾其他進程的地址空間。

進程包含了程序執行時的運行上下文信息,運行上下文是指進程在執行過程中所涉及的各種狀態和數據,主要包括程序計數器、寄存器狀態、信息、內存管理信息等。程序計數器指示了進程下一條要執行的指令地址,寄存器用于臨時存儲數據和指令操作數等,用于保存函數調用的相關信息和局部變量等。這些運行上下文信息完整地描述了進程當前的執行狀態。當進程被調度暫停或恢復執行時,操作系統需要保存和恢復這些上下文信息,以確保進程能夠正確地繼續執行。

進程是構成操作系統中并發執行環境的基本單元,操作系統通過管理和調度多個進程,實現了多個任務的并發執行,從而提高了系統資源的利用率和系統的整體性能。多個進程之間可以通過各種進程間通信機制進行數據交換和協作,共同完成復雜的系統任務。

下圖是我們在Windows中的進程。

【Linux】從硬件到軟件了解進程 進程粗略來講就是內核PCB數據結構對象加上你自己的代碼和數據。記住上面所說的先描述后組織,通過結構體描述進程的屬性,然后通過鏈表組織多個進程。

2、PCB和task_Struct進程的所有信息被存放在一個叫做進程控制塊的數據結構中,它是進程屬性的集合,被稱為PCB。

Linux操作系統下的PCB就是task_struct,它是一個結構體,被裝載到RAM里。

以下是task_struct的內容分類,除了這些,還有一些其他信息。

內容 意義

標示符

每個進程的標識符不同

狀態

任務狀態

優先級

相對于其他進程的優先級

程序計數器

程序中即將被執行的下一條指令的地址

內存指針

包括程序代碼和進程相關數據的指針,還有和其他進程共享的內存塊的指針

上下文數據

進程執行時處理器的寄存器中的數據

IO狀態

顯示的IO請求,分配給進程的IO設備和被進程使用的文件列表

記賬信息

處理器時間總和或使用的時鐘數總和或時間限制、記賬號等

所有運行在系統里的進程都以task_struct(雙向)鏈表的形式存在內核里。

3、查看進程寫一個死循環的程序,方便我們查看進程。

【Linux】從硬件到軟件了解進程【Linux】從硬件到軟件了解進程ps aux 會列出系統中所有用戶的所有進程的詳細信息,grep process 會在 ps aux 輸出的所有行中查找包含 process 的行,并將這些行輸出。grep 是要排除的模式,由于在執行 grep process 時,這個 grep 命令本身也會作為一個進程被 ps aux 列出,并且會匹配 process,為了避免將 grep process 這個進程本身顯示出來,我們使用 grep -v grep 來過濾掉包含 grep 的行。

在程序執行過程中會生成一個進程,我們通過查看進程指令,其中第二列就是進程唯一標識PID,第一列是父進程唯一標識PPID,該進程沒有父進程,所以第一列不顯示。

【Linux】從硬件到軟件了解進程進程重啟對應的PID會發生變化,是由于內存重新給它分配的原因。

【Linux】從硬件到軟件了解進程這里解答一下為什么我們在進行./process的時候會啟動可執行文件process:在進程中有一個目錄叫做cwd,意味著當前的工作目錄,你可以把它想象為一個指針(其實它是一個軟鏈接),指向這個文件所在的目錄,所以一個進程在屬性中就有一個是當前的工作目錄。亦可以看到exe這里指向的是這里的我們正在執行的可執行程序process。

【Linux】從硬件到軟件了解進程4、通過系統調用fork創建進程(1)簡述上面的進程是在執行可執行程序的時候程序自動構建的進程,這節我們要通過系統調用fork創建進程。

寫一個fork創建進程的程序如下test.c,在我們現有的知識體系里,在fork函數自身不出現問題的情況下給到的id值是大于等于0的值,屬于雙分支結構,即id值要不然就等于0要不然就大于0,不會出現即等于0又大于0的情況,本身兩種情況同時出現就是錯誤的。

【Linux】從硬件到軟件了解進程【Linux】從硬件到軟件了解進程【Linux】從硬件到軟件了解進程 看到結果,兩個分支的程序都會執行,就是因為fork這里的原因,生成了子進程,改變了我們對該程序固有的看法,現在我們來研究fork是如何做到的。

(2)系統調用生成子進程的過程〇提出問題該過程我們可以簡化為一個問題:為什么id在等于0的同時又大于0? id值是從fork函數來的,那么進一步提出問題:fork為什么能產生兩個返回值? id為什么能承載兩個返回值?

最終我們將目光移動到fork函數身上。

①fork函數fork系統調用用于從一個現有的進程創建一個新的進程,新創建的進程被稱為子進程,而原來的進程被稱為父進程。子進程是父進程的一個副本,它幾乎繼承了父進程的所有資源,包括代碼段、數據段、堆、棧等,但擁有自己獨立的進程控制塊(PCB)和進程 ID(PID)。

在父進程中,fork返回子進程的 PID,因為父進程可能需要對多個子進程進行管理和控制,所以通過返回的 PID 來標識每個子進程。在子進程中,fork返回 0,這是因為子進程不需要知道父進程的 PID 來進行后續操作,它可以通過getppid函數來獲取父進程的 PID。如果fork調用失敗,將返回 – 1,并設置errno變量來表示錯誤原因。

②父子進程關系進程可以粗略表示為代碼+數據。當父進程調用fork時,內核會為子進程分配新的 PCB,并復制父進程的大部分資源到子進程中,這包括進程的代碼部分。雖然子進程最初復制了父進程的地址空間,但在實際運行中,父子進程的地址空間是相互獨立的。如果其中一個進程修改了某些數據,不會影響到另一個進程中的相應區域,這是通過寫時復制技術來實現的,即只有當進程試圖修改某個數據時,才會真正復制該數據,以節省內存資源,就是說在不修改某些數據的情況下它們指向的是同一塊位置,如果子進程或者父進程某些數據要修改,它們會重新開辟一塊空間存放該進程的特有數據。fork調用完成后,父進程和子進程就開始并發執行,它們可以各自獨立地執行不同的代碼路徑,也可以通過各種進程間通信機制進行通信和同步,這里就是從fork函數出現之后的代碼我們可以把它當做兩份,兩份代碼同時跑,但是id不同,后面執行的效果可能就不同。

并且我們可以發現上面的截圖父子進程誰先運行是不確定的,這個是由調度器決定的。

③解答問題問:id為什么能承載兩個返回值?答:id變量并不是同時承載兩個返回值,而是在不同的執行流(父進程和子進程)中被賦予不同的值,fork函數通過這種方式讓父進程和子進程能夠區分彼此,并根據返回值執行不同的操作。

問:fork為什么能產生兩個返回值?答:父子進程并發執行,每個執行流從fork函數的返回處繼續執行,并且根據自身的角色(父進程或子進程)返回不同的值,這樣就實現了一個函數調用在兩個進程中產生不同返回結果的效果。

相關閱讀

主站蜘蛛池模板: 久草中文在线 | 亚洲黄网址 | 一道精品视频一区二区三区图片 | 68 日本xxxxxxxxx 视频 | 成年大片免费视频播放二级 | 精品国产96亚洲一区二区三区 | 欧美男女网站 | 免费特黄级夫费生活片 | 欧洲成人r片在线观看 | 亚洲人成影院午夜网站 | 国产欧美在线一区二区三区 | 日本免费二区三区久久 | 久久91精品国产91久久户 | 99久久99久久久精品久久 | 精品一久久香蕉国产线看播放 | 欧美成人免费sss | 理论片免费午夜 | 国内久久精品视频 | 国产在线91精品入口首页 | 男人的天堂高清在线观看 | 日韩理论在线 | 国产美女又黄又爽又色视频免费 | 亚洲最新 | 久草视频播放 | 成人免费福利网站在线看 | 三级手机在线观看 | 视频一区在线 | 欧美日韩在线视频免费完整 | 国产性自拍| 一级特黄aaa免费 | 国产在线一二三区 | 国产精品视频99 | 萌白酱喷水福利视频在线 | 亚洲精品久久九九热 | 99ri在线精品视频在线播放 | 亚洲欧美卡通成人制服动漫 | 亚洲一级免费视频 | 欧美一级毛片片免费 | 国产成年网站v片在线观看 国产成人aa在线视频 | 国产一级爱做片免费观看 | 国产成人精品日本亚洲网站 |