主頁 > 作業系統 > 面試基礎篇|作業系統|行程

面試基礎篇|作業系統|行程

2021-11-03 06:01:56 作業系統

行程

關于行程和執行緒方面的知識相信大家都很熟悉,因為這是作業系統里面最基礎也是最重要的內容,而且在面試的時候,面試官很喜歡問這方面的問題,所以有必要深刻的理解一下這部分的內容,

首先,什么行程?

行程的概念

簡言之,一個行程就是一個正在執行程式的實體,包括程式計數器、暫存器和變數的當前值,從概念上說,每個行程擁有它自己的虛擬CPU,當然,實際上真正的CPU在各行程之間來回切換,

這里要把行程和程式區分開,程式是行程的一部分,行程主要包括以下內容:

  • 文本段(text section)(或代碼段(code section))
  • 程式計數器(programcounter)的值
  • 處理器暫存器的內容
  • 行程堆疊(stack)(包括臨時資料,如函式引數、回傳地址和區域變數)
  • 資料段(data section)(包括全域變數)
  • 堆(heap)(行程運行時動態分配的記憶體)

可以看到,行程與程式的區別在于:

  1. 行程是動態的,程式是靜態的

    • 程式是有序代碼的集合
    • 行程是程式的執行,行程有核心態/用戶態
  2. 行程是暫時的,程式的永久的

    • 行程是一個狀態變化的程序
    • 程式可長久保存
  3. 行程與程式的組成不同

    行程的組成包括程式、資料和行程控制塊

一個行程是某種型別的一個活動,它有程式、輸入、輸出以及狀態,單個處理器可以被若干行程共享,它使用某種調度演算法決定何時停止一個行程的作業,并轉而為另一個行程提供服務,

程式本身不是行程,程式只是被動(passive) 物體,如存盤在磁盤上包含一系列指令的檔案(經常稱為可執行檔案(executable file) ),相反,行程是活動(active) 物體,具有一個程式計數器用于表示下個執行命令和一組相關資源,當一個可執行檔案被加載到記憶體時,這個程式就成為行程,

簡言之,程式只是行程的一部分,總結一下行程的特征:

  • 動態性:行程是程式的一次執行程序,是臨時的,有生命期的,是動態產生,動態消亡的
  • 并發性任何行程都可以同其他進行一起并發執行;
  • 獨立性:行程是系統進行資源分配和調度的一個獨立單位
  • 結構性:行程由程式,資料和行程控制塊三部分組成,

下面來看行程是如何實作的,

行程實作

為了實作行程模型,作業系統維護著一張表格(一個結構陣列),即行程表(process table)每個行程占用一個行程表項,稱為行程控制塊(Process Control Block, PCB),表項包含了行程狀態的重要資訊,包括程式計數器、堆疊指標、記憶體分配狀況、所打開檔案的狀態、賬號和調度資訊,以及其他在行程由運行態轉換到就緒態或阻塞態時必須保存的資訊,從而保證該行程隨后能再次啟動,就像從未被中斷過一樣,

行程控制塊的關鍵欄位:

在這里插入圖片描述

第一列中的欄位與行程管理有關,其他兩列分別與存盤管理和檔案管理有關,

接下來看一下行程是如何創建的,

行程創建

關于行程創建的時機,主要有4種主要事件導致行程的創建:

1、系統初始化

啟動作業系統時,系統會創建若干行程,有和用戶互動的前臺行程,同時也有很多后臺行程,停留在后臺處理諸如電子郵件、Web頁面、新聞、列印之類活動的行程稱為守護行程(daemon)

2、執行了正在運行的行程所呼叫的行程創建系統呼叫,

一個正在運行的行程經常發出系統呼叫,以便創建一個或多個新行程協助其作業,

3、用戶請求創建一個新行程,

在互動式系統中,鍵入一個命令或者點(雙)擊一個圖示就可以啟動一個程式,

4、一個批處理作業的初始化,

用戶在批處理系統中提交批處理作業,在作業系統認為有資源可運行另一個作業時,它創建一個新的行程,并運行其輸入佇列中的下一個作業,

可以看到,在所有這些情形中,新行程都是由于一個已存在的行程執行了一個用于創建行程的系統呼叫而創建的,創建行程稱為父行程,而新的行程稱為子行程,每個新行程可以再創建其他行程,從而形成行程樹( process tree),

當一個行程創建子行程時,該子行程會需要一定的資源(CPU時間、記憶體、檔案、I/O設備等)來完成任務,子行程可以從作業系統那里直接獲得資源,也可以只從父行程那里獲得資源子集父行程可能要在子行程之間分配資源或共享資源(如記憶體或檔案)

限制子行程只能使用父行程的資源,可以防止創建過多行程,導致系統超載,

當行程創建新行程時,可有兩種執行可能:

  • 父行程與子行程并發執行,
  • 父行程等待,直到某個或全部子行程執行完,

新行程的地址空間也有兩種可能:

  • 子行程是父行程的復制品(它具有與父行程同樣的程式和資料),
  • 子行程加載另一個新程式,

我們具體來看一下Unix和Windows系統下行程的創建,

Unix系統的行程創建

在UNIX系統中,只有一個系統呼叫可以用來創建新行程:fork,這個系統呼叫會創建一個與呼叫行程相同的副本,在呼叫了fork后,這兩個行程(父行程和子行程)擁有相同的存盤映像、同樣的環境字串和同樣的打開檔案,這就是全部情形,通常,子行程接著執行exec()或一個類似的系統呼叫,以修改其存盤映像并運行一個新的程式,

新行程的地址空間復制了原來行程的地址空間,這種機制允許父行程與子行程輕松通信,這兩個行程(父和子)都繼續執行處于系統呼叫fork()之后的指令,但有一點不同:對于新(子)行程,系統呼叫fork()的回傳值為0 ;而對于父行程,回傳值為子行程的行程識別符號(非零),

通常,在系統呼叫fork()之后,有個行程使用系統呼叫exec(),以用新程式來取代行程的記憶體空間,系統呼叫exec()加載二進制檔案到記憶體中(破壞了包含系統呼叫exec()的原來程式的記憶體內容),并開始執行,

父行程能夠創建更多子行程,或者如果在子行程運行時沒有什么可做.那么它采用系統呼叫wait()把自己移出就緒佇列,直到子行程終止,因為呼叫exec()用新程式覆寫了行程的地址空間,所以呼叫exec()除非出現錯誤,不會回傳控制,

大多數的作業系統(包括UNIX、Linux和Windows) 對行程的識別采用的是唯一的行程識別符號(process identifier, pid),這通常是一個整數值,系統內的每個行程都有一個唯一pid,它可以用作索引,以便訪問內核中的行程的各種屬性,

在這里插入圖片描述

Windows的行程創建

行程創建采用Windows API函式CreateProcess() ,它類似于fork() (這是父行程用于創建子行程的),不過,fork()讓子行程繼承了父行程的地址空間,而CreateProcess()在行程創建時要求將一個特定程式加載到子行程的地址空間,

再者,fork()不需要傳遞任何引數,而CreateProcess()需要傳遞至少10個引數,其中包括要執行的程式、輸入給該程式的命令列引數、各種安全屬性、有關打開的檔案是否繼承的控制位、優先級資訊、為該行程(若有的話)所需要創建的視窗規格以及指向一個結構的指標,在該結構中新創建行程的資訊被回傳給呼叫者,

總結一下:

在UNIX和Windows中,行程創建之后,父行程和子行程有各自不同的地址空間,

  • 在UNIX中,子行程的初始地址空間是父行程的一個副本,但是這里涉及兩個不同的地址空間,不可寫的記憶體區是共享的(某些UNIX的實作使程式正文在兩者間共享,因為它不能被修改),但是,對于一個新創建的行程而言,確實有可能共享其創建者的其他資源,諸如打開的檔案等,
  • 在Windows中,從一開始父行程的地址空間和子行程的地址空間就是不同的,

行程不可能一直存在,有行程的創建就必然有行程的終止,

行程終止

引起行程終止的條件也主要有四種:

  1. 正常退出(自愿的)
  2. 出錯退出(自愿的)
  3. 嚴重錯誤(非自愿)
  4. 被其他行程殺死(非自愿)

當行程完成執行最后陳述句并且通過系統呼叫exit()請求作業系統洗掉自身時,行程終止,這時,行程可以回傳狀態值(通常為整數)到父行程(通過系統呼叫wait()),所有行程資源,如物理和虛擬記憶體、打開檔案和I/O緩沖區等,會由作業系統釋放,

通常,只有終止行程的父行程才能執行這一系統呼叫,否則,用戶可以任意終止彼此的作業,記住,如果終止子行程,則父行程需要知道這些子行程的識別符號,因此,當一個行程創建新行程時,新創建行程的識別符號要傳遞到父行程,

父行程終止子行程的原因有很多,如:

  • 子行程使用了超過它所分配的資源,(為判定是否發生這種情況,父行程應有一個機制,以檢查子行程的狀態),
  • 分配給子行程的任務,不再需要,
  • 父行程正在退出,而且作業系統不允許無父行程的子行程繼續執行,

父行程可以通過系統呼叫wait(),等待子行程的終止,系統呼叫wait()可以通過引數,讓父行程獲得子行程的退出狀態;這個系統呼叫也回傳終止子行程的識別符號,這樣父行程能夠知道哪個子行程已經終止了 ,

當一個行程終止時,作業系統會釋放其資源,不過,它位于行程表中的條目還是在的,直到它的父行程呼叫wait() ;這是因為行程表包含了行程的退出狀態,

當行程已經終止,但是其父行程尚未呼叫wait(),這樣的行程稱為僵尸行程(zombie process),

所有行程終止時都會過渡到這種狀態,但是一般而言僵尸行程只是短暫存在一旦父行程呼叫了 wait(),僵尸行程的行程識別符號和它在行程表中的條目就會釋放,

如果父行程沒有呼叫wait()就終止以致于子行程成為孤兒行程(orphan process),

Linux和UNIX對這種情況的處理是:將init行程作為孤兒行程的父行程,行程init定期呼叫wait(),以便收集任何孤兒行程的退出狀態,并釋放孤兒行程識別符號和行程表目,

行程從創建到終止的程序中,其狀態可能會不斷的改變,在各種狀態之間相互切換,

行程狀態

行程主要的5種狀態:

  1. 運行狀態(Running)

    行程正在處理機上運行,

  2. 就緒狀態(Ready)

    行程獲得了除了處理機之外的所有所需的資源,得到處理機即可運行,

  3. 阻塞狀態(Block)

    行程正在等待某一事件的出現而暫停運行,

  4. 創建狀態(New)

    一個行程正在被創建,還沒被轉到就緒狀態之前的狀態,是一個過渡狀態,也就是在分配資源和相應的資料結構

  5. 退出狀態(Exit)

    一個行程反正在從系統中消失時的狀態,這是因為行程結束或者由于其他原因所致(也就是系統正在回收資源),

在這里插入圖片描述

轉換1:運行態到阻塞態

運行的行程需要等待I/O或者其他行程的結果作為輸入,此時行程自動阻塞,

轉換2:運行態到就緒態

一個行程運行的時間片用完或被高優先級的行程搶占,

轉換3:就緒態到運行態

輪到就緒行程運行時,

轉換4:阻塞態到就緒態

當行程等待的一個外部事件發生時(如一些輸入到達),

當行程從運行態轉換為就緒態時,這時候其他的行程在得到了處理機,這個程序發生了行程切換,

行程切換

切換CPU到另一個行程需要保存當前行程狀態和恢復另一個行程的狀態, 這個任務稱為背景關系切換(context switch),當進行背景關系切換時, 內核會將舊行程狀態保存在其PCB中, 然后加載經調度而要執行的新行程的背景關系,

背景關系切換的時間是純粹的開銷, 因為在切換時系統并沒有做任何有用作業, 背景關系切換的速度因機器不同而有所不同, 它依賴于記憶體速度、 必須復制的暫存器數量、 是否有特殊指令(如加載或存盤所有暫存器的單個指令),典型速度為幾毫秒,

所以行程的切換是非常耗時的,浪費了cpu的資源,所以引入了執行緒的概念,

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

標籤:Linux

上一篇:即使構建成功,也缺少“MavenDependencies”檔案夾

下一篇:面試基礎篇|作業系統|行程

標籤雲
其他(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)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more