每天3分鐘操作系統修煉秘籍(24):進程狀態以及狀態轉換

来源:https://www.cnblogs.com/f-ck-need-u/archive/2020/02/29/12381701.html
-Advertisement-
Play Games

"點我查看秘籍連載" 進程狀態以及狀態轉換 進程並非總是處於運行中,例如CPU沒運行在它身上時它就是非運行的。進程在創建之後會改變狀態,不同的狀態之間可以實現狀態切換,可以通過ps或top等命令捕獲進程的狀態。包含以下幾種狀態: 創建態(new):進程正在被創建中,過程非常短暫,用戶無法捕捉 運行態 ...


點我查看秘籍連載

進程狀態以及狀態轉換

進程並非總是處於運行中,例如CPU沒運行在它身上時它就是非運行的。進程在創建之後會改變狀態,不同的狀態之間可以實現狀態切換,可以通過ps或top等命令捕獲進程的狀態。包含以下幾種狀態:

  • 創建態(new):進程正在被創建中,過程非常短暫,用戶無法捕捉
  • 運行態(running):進程正在執行中,即CPU正在該進程上
  • 就緒態(ready):進程已經準備好可以運行,存放在就緒隊列中等待被調度,操作系統調度時將從就緒隊列中選擇下一個要運行的進程
  • 阻塞態(waiting/sleeping/blocking):也稱為睡眠態,進程因為某些原因(如等待IO完成或等待其它事件發生)停止了、睡眠了、阻塞了,CPU轉讓出去,調度時也不會調度到它
  • 終止態(terminated):進程執行完成或發生某種特殊事件,進程將退出,但還未被內核清理(顯然,如果已被清理,任何手段都無法捕獲到該進程的信息),這就是終止狀態,也是僵屍態(Zombie或Defunct)

進程在發生某些事件之後會改變自己的狀態,各狀態之間的轉換方式如圖:(如果不好理解,可參考稍後的示例分析)

其中:

上面的狀態轉換中,主要關註的是運行態、就緒態、睡眠態這3者之間的轉換。

運行態轉為就緒態表示當前正在執行的進程已經耗盡了分配給它的時間片,只能交出CPU的控制權,自己進入到就緒隊列等待下次被調度選中後繼續運行。

就緒態轉為運行態表示調度器從就緒隊列中調度進程時,正好選中了該進程,於是該進程將獲取到CPU並開始執行。

運行態轉為睡眠態一般是等待某事件的出現,在事件出現之前,進程無法繼續執行,只能先暫停進入到睡眠態,例如等待信號通知、等待IO完成。信號通知很容易理解,而對於IO等待(比如想要從磁碟文件中讀取一行數據,等待用戶敲下一個字元,等待數據全部輸出到終端屏幕等等),假如在發生IO等待的時候進程繼續保持運行態,它必將繼續持有CPU直到IO的完成,但這個時候的進程根本沒有繼續向下執行,而是完全處於無謂的等待中, CPU在這時候也沒有做任何事情,處於空轉狀態,由於IO操作相比於CPU來說是非常慢的,而CPU是極其珍貴的資源,不能隨意浪費,所以出現IO等待的進程都應該進入阻塞狀態,交出CPU讓它去處理其它進程。

睡眠態轉為就緒態表示睡眠的進程所等待的事件已經發生了,這個睡眠的進程已經可以繼續執行了,於是內核喚醒該進程,將其放入到就緒隊列中等待下次被調度到繼續執行。

註意沒有"就緒 -> 睡眠"和"睡眠 -> 運行"的狀態切換,這很容易理解。不存在"就緒 -> 睡眠"是因為就緒態的進程本就是停止的,當然不可能發生因等待某些事件而進入到睡眠態,只有正在運行中的進程才可能會需要等待某些事件才進入睡眠態。不存在"睡眠 -> 運行"是因為調度器只會從就緒隊列中挑出下一次要運行的進程,所以睡眠態的進程等待的事件完成後,也必須先放入到就緒隊列中,才能等待被調度執行。

關於進程的狀態,還有幾點需要說明。

  1. 睡眠態是一個非常寬泛的概念,分為可中斷睡眠(interruptiable sleep)和不可中斷睡眠(un-interruptiable sleep)
    • 可中斷睡眠是允許接收外界信號和內核信號而被喚醒的睡眠,絕大多數睡眠都是可中斷睡眠,能ps或top捕捉到的睡眠也幾乎總是可中斷睡眠;
    • 不可中斷睡眠只能由內核發起信號來喚醒,外界無法通過信號來喚醒,只能在事件完成後由內核喚醒,主要表現在和硬體交互的時候。例如cat一個文件時需要從硬碟上載入數據到記憶體中,在和硬體交互的那段時間一定是不可中斷的睡眠,否則在載入數據的時候突然被人為發送的信號手動喚醒,而被喚醒時和硬體交互的過程又還沒完成,那麼即使喚醒了也沒法將cpu交給它運行。而且,不可中斷睡眠若能被人為喚醒,更嚴重的後果是硬體崩潰。由此可知,不可中斷睡眠是為了保護某些重要進程,也是為了讓cpu不被浪費。
  2. 終止態表示的是進程已被終止(比如已經執行完了所有任務),但是內核還沒有將這個進程從內核表項中清理掉。所以,終止態是進程消失前的一個狀態,因為如果進程已被內核清理,任何手段都無法去捕獲該進程的信息。這個狀態其實就是常說的僵屍態,這個狀態是非常重要的狀態,後文還會詳細介紹僵屍進程。
  3. 除了上面描述的幾種狀態,通常還有一種狀態稱為stopped狀態,它也是一種睡眠態進程,只是比較特殊:它可以通過信號手動喚醒然後繼續運行,所以它是一種可中斷睡眠狀態。之所以要從睡眠態中區分出stopped狀態,主要是為shell的作業提供一種控制手段的。例如,可以按下ctrl+z讓前臺運行的命令進入到Stopped狀態,因為進入到了stopped狀態就是進入了睡眠態,所以放棄CPU,該進程自然就進入到後臺,這其實是發送了SIGTSTP信號給該進程(所以也可以通過kill命令手動發送該信號給進程使其進入stopped狀態);另外,對stopped狀態的進程可以手動發送SIGCONT信號,使其從stopped狀態恢復,也就是喚醒該進程,使其進入到就緒隊列等待被調度繼續執行,此外,shell作業控制的兩個命令fg和bg命令其實在內部都會發送SIGCONT信號。關於信號和shell的作業控制,後面的文章會詳細介紹。

示例分析進程轉換

前面說了一大段關於進程的狀態已經進程狀態轉換的理論,現在用一個簡單的示例分析一下,這個示例如果瞭解fork和exec會更容易理解,不知道也沒關係,稍後會介紹。

假如,在命令行下執行一個"cat a.log"命令。

首先,shell(比如bash)需要解析命令行,比如檢查命令行語法,命令行解析完成後(通過fork())創建一個新的進程(bash進程的子進程),併為其分配好記憶體,進程在創建過程中處於創建態,創建完成後立即放入就緒隊列中成為就緒態進程,此時進程還不叫cat進程,而是子bash進程。

當調度到該進程後,進程轉變為運行態,它將(通過exec函數)調用cat程式將其載入到記憶體中覆蓋替換子bash進程,這個時候的進程才叫做cat進程,於是cat進程開始執行。

cat進程執行時,發現要讀取文件,但是cat進程是用戶模式下的進程,它沒有許可權打開文件,於是通過open()系統調用請求操作系統幫忙打開,於是陷入到內核,內核進程幫忙打開文件後返回一個文件描述符給cat進程併進入用戶模式下,cat進程通過該文件描述符讀取a.log文件,但是當它開始讀數據的時候,cat仍然無許可權讀取文件數據,於是通過read()系統調用請求操作系統幫忙讀取,操作系統將讀取到的數據放入記憶體,然後回到cat進程,cat進程直接從記憶體中讀取數據,並將讀取到的數據輸出到終端屏幕,但是cat進程仍然沒有許可權執行寫終端硬體(Linux下設備也是文件),於是又發送write()系統調用請求操作系統幫忙寫數據到終端,於是數據顯示在屏幕上。

上面的過程中,讀取磁碟文件數據、輸出數據到屏幕都是速度非常慢的IO操作,cat進程都將在這些過程發生時(即IO等待時)進入到不可中斷睡眠狀態,當IO完成時cat進程將進入就緒態,當再次調度到cat進程時,cat進程將轉為運行態。

當輸出數據完成後,cat進程將終止退出,於是進入終止態或者僵屍態等待內核清理該進程,直到內核清理該進程後,cat進程將永久的消失。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 背景 By 魯迅 By 高爾基 說明: 1. Kernel版本:4.14 2. ARM64處理器,Contex A53,雙核 3. 使用工具:Source Insight 3.5, Visio 1. 概述 進程切換:內核將CPU上正在運行的進程掛起,選擇下一個進程來運行。 ARM架構中,CPU上一次 ...
  • 1. Prometheus配置方式有兩種 命令行,用來配置不可變命令參數,主要是Prometheus運行參數,比如數據存儲位置 配置文件,用來配置Prometheus應用參數,比如數據採集,報警對接 不重啟進程配置生效方式也有兩種 對進程發送信號SIGHUP HTTP POST請求,需要開啟 web ...
  • 簡介:Nextcloud是一款開源免費的私有雲存儲網盤項目,可以讓你快速便捷地搭建一套屬於自己或團隊的雲同步網盤,從而實現跨平臺跨設備文件同步、共用、版本控制、團隊協作等功能。它的客戶端覆蓋了Windows、Mac、Android、iOS、Linux 等各種平臺,也提供了網頁端以及 WebDAV介面 ...
  • Windows操作系統的帳號角色許可權 1.Windows操作系統的帳戶: • Windows操作系統好比一間富麗堂皇的宮殿,大門的門鎖是身份和許可權鑒別器,到訪人員是賬戶,鑰匙是驗證其身份和許可權的措施。 <1.>本地系統帳戶,Local System Account 本地管理員帳戶,Local Adm ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" 數組 awk數組特性: awk的數組是關聯數組(即key/value方式的hash數據結構),索引下標可為數值(甚至是負數、小數等),也可為字元串 在內部,awk數組的索引全都是字元串,即使是數值索引在使用時內部也會轉換成字 ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" break和continue break可退出for、while、do...while、switch語句。 continue可讓for、while、do...while進入下一輪迴圈。 next和nextfile next會 ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" 流程式控制制語句 註:awk中語句塊沒有作用域,都是全局變數。 代碼塊 if...else 搞笑題:妻子告訴程式員老公,去買一斤包子,如果看見賣西瓜的,就買兩個。結果是買了兩個包子回來。 switch...case awk 中的 ...
  • 回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" awk布爾值 在awk中,沒有像其它語言一樣專門提供true、false這樣的關鍵字。 但它的布爾值邏輯非常簡單: 數值0表示布爾假 空字元串表示布爾假 其餘所有均為布爾真 字元串"0"也是真,因為它是字元串 awk中,正則 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...