用戶態和內核態的概念區別

来源:http://www.cnblogs.com/think-in-java/archive/2016/09/30/5924183.html
-Advertisement-
Play Games

1. 用戶態和內核態的概念區別 究竟什麼是用戶態,什麼是內核態,這兩個基本概念以前一直理解得不是很清楚,根本原因個人覺得是在於因為大部分時候我們在寫程式時關註的重點和著眼的角度放在了實現的功能和代碼的邏輯性上,先看一個例子: 1)例子 C代碼 void testfork(){ if(0 = = fo ...


1. 用戶態和內核態的概念區別

究竟什麼是用戶態,什麼是內核態,這兩個基本概念以前一直理解得不是很清楚,根本原因個人覺得是在於因為大部分時候我們在寫程式時關註的重點和著眼的角度放在了實現的功能和代碼的邏輯性上,先看一個例子:

1)例子

 

C代碼

  

void testfork(){  
if(0 = = fork()){  
printf(“create new process success!\n”);  
}  
printf(“testfork ok\n”);  
}  

 

 

 

這段代碼很簡單,從功能的角度來看,就是實際執行了一個fork(),生成一個 新的進程,從邏輯的角度看,就是判斷瞭如果fork()返回的是0則列印相關語句,然後函數最後再列印一句表示執行完整個testfork()函數。代碼 的執行邏輯和功能上看就是如此簡單,一共四行代碼,從上到下一句一句執行而已,完全看不出來哪裡有體現出用戶態和進程態的概念。

如果說前面兩種是靜態觀察的角度看的話,我們還可以從動態的角度來看這段代碼,即它被轉換成CPU執行的指令後載入執行的過程,這時這段程式就是一個動態執行的指令序列。而究竟載入了哪些代碼,如何載入就是和操作系統密切相關了。

 

2)特權級

熟悉Unix/Linux系統的人都知道,fork的工作實際上是以系統調用的 方式完成相應功能的,具體的工作是由sys_fork負責實施。其實無論是不是Unix或者Linux,對於任何操作系統來說,創建一個新的進程都是屬於 核心功能,因為它要做很多底層細緻地工作,消耗系統的物理資源,比如分配物理記憶體,從父進程拷貝相關信息,拷貝設置頁目錄頁表等等,這些顯然不能隨便讓哪 個程式就能去做,於是就自然引出特權級別的概念,顯然,最關鍵性的權力必須由高特權級的程式來執行,這樣才可以做到集中管理,減少有限資源的訪問和使用沖 突。

特權級顯然是非常有效的管理和控製程序執行的手段,因此在硬體上對特權級做了很 多支持,就Intel x86架構的CPU來說一共有0~3四個特權級,0級最高,3級最低,硬體上在執行每條指令時都會對指令所具有的特權級做相應的檢查,相關的概念有 CPL、DPL和RPL,這裡不再過多闡述。硬體已經提供了一套特權級使用的相關機制,軟體自然就是好好利用的問題,這屬於操作系統要做的事情,對於 Unix/Linux來說,只使用了0級特權級和3級特權級。也就是說在Unix/Linux系統中,一條工作在0級特權級的指令具有了CPU能提供的最 高權力,而一條工作在3級特權級的指令具有CPU提供的最低或者說最基本權力。

 

3)用戶態和內核態

現在我們從特權級的調度來理解用戶態和內核態就比較好理解了,當程式運行在3級 特權級上時,就可以稱之為運行在用戶態,因為這是最低特權級,是普通的用戶進程運行的特權級,大部分用戶直接面對的程式都是運行在用戶態;反之,當程式運 行在0級特權級上時,就可以稱之為運行在內核態。

雖然用戶態下和內核態下工作的程式有很多差別,但最重要的差別就在於特權級的不 同,即權力的不同。運行在用戶態下的程式不能直接訪問操作系統內核數據結構和程式,比如上面例子中的testfork()就不能直接調用 sys_fork(),因為前者是工作在用戶態,屬於用戶態程式,而sys_fork()是工作在內核態,屬於內核態程式。

當我們在系統中執行一個程式時,大部分時間是運行在用戶態下的,在其需要操作系 統幫助完成某些它沒有權力和能力完成的工作時就會切換到內核態,比如testfork()最初運行在用戶態進程下,當它調用fork()最終觸發 sys_fork()的執行時,就切換到了內核態。

 

2. 用戶態和內核態的轉換

1)用戶態切換到內核態的3種方式

a. 系統調用

這是用戶態進程主動要求切換到內核態的一種方式,用戶態進程通過系統調用申請使 用操作系統提供的服務程式完成工作,比如前例中fork()實際上就是執行了一個創建新進程的系統調用。而系統調用的機制其核心還是使用了操作系統為用戶 特別開放的一個中斷來實現,例如Linux的int 80h中斷。

b. 異常

當CPU在執行運行在用戶態下的程式時,發生了某些事先不可知的異常,這時會觸發由當前運行進程切換到處理此異常的內核相關程式中,也就轉到了內核態,比如缺頁異常。

c. 外圍設備的中斷

當外圍設備完成用戶請求的操作後,會向CPU發出相應的中斷信號,這時CPU會 暫停執行下一條即將要執行的指令轉而去執行與中斷信號對應的處理程式,如果先前執行的指令是用戶態下的程式,那麼這個轉換的過程自然也就發生了由用戶態到 內核態的切換。比如硬碟讀寫操作完成,系統會切換到硬碟讀寫的中斷處理程式中執行後續操作等。

 

這3種方式是系統在運行時由用戶態轉到內核態的最主要方式,其中系統調用可以認為是用戶進程主動發起的,異常和外圍設備中斷則是被動的。

 

2)具體的切換操作

從觸發方式上看,可以認為存在前述3種不同的類型,但是從最終實際完成由用戶態 到內核態的切換操作上來說,涉及的關鍵步驟是完全一致的,沒有任何區別,都相當於執行了一個中斷響應的過程,因為系統調用實際上最終是中斷機制實現的,而 異常和中斷的處理機制基本上也是一致的,關於它們的具體區別這裡不再贅述。關於中斷處理機制的細節和步驟這裡也不做過多分析,涉及到由用戶態切換到內核態 的步驟主要包括:

[1] 從當前進程的描述符中提取其內核棧的ss0及esp0信息。

[2] 使用ss0和esp0指向的內核棧將當前進程的cs,eip,eflags,ss,esp信息保存起來,這個

過程也完成了由用戶棧到內核棧的切換過程,同時保存了被暫停執行的程式的下一

條指令。

[3] 將先前由中斷向量檢索得到的中斷處理程式的cs,eip信息裝入相應的寄存器,開始

執行中斷處理程式,這時就轉到了內核態的程式執行了。

 

原文出自:http://longmans1985.blog.163.com/blog/static/7060547520109262178736/


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

-Advertisement-
Play Games
更多相關文章
  • 參考閱讀:http://www.manongjc.com/article/1205.html 最近遇到一個修改 MySQL 表類型的問題,以前在 phpmyadmin 管理 mysql 資料庫時,建立的表預設是 MyISAM 類型,而且修改表類型也比較方便。奈何現在配置 phpmyadmin 出了問 ...
  • 查看被鎖表: 解除鎖: 查看被鎖表: spid 鎖表進程 tableName 被鎖表名 解鎖: ...
  • select ext.org_channel_type as ORG_CHANNEL_TYPE from channel.channel_pub_info i left join channel.sec_organize_ext ext on i.channel_id = ext.organize_ ...
  • 一、游標的使用並不難,游標其實就是編程中的for迴圈,只不過在資料庫中寫法不同而已。 DECLARE My_Cursor CURSOR --創建游標讀取數據 FOR select id,name from 表--數據源 OPEN My_Cursor; --打開游標 FETCH NEXT FROM M ...
  • 在做報表的時候,通常會遇到要把查詢出的數據做為列頭顯示,但是查詢出來的數據會根據條件的不同查詢出的數據也就不同(動態列),那麼列頭也不同。 這個時候就需要把查詢出數據的行轉換成列。 一、將查詢出來的數據轉換成列頭 declare @Str varchar(500); Create Table #t_ ...
  • 每次配置Samba 都需要上網去查資料,而且有一些不一定適合。所以自己就簡單記錄一下 1、Samba的安裝 // ( ) //舊版本 //新版本 上面的命令將會安裝 和其他相關的工具。在舊版的 中,你可能需要使用 替代 。 2、創建共用目錄 系統用戶home目錄下: //如果配置的共用目錄不存在則創 ...
  • 忠告初學者學習Linux系統的8點建議 新手或者說即將要入坑的小伙伴們,常常在QQ群或者在Linux論壇問一些問題,不過,其中大多數的問題都是很基礎的。例如:如何給添加的用戶歸屬用戶組,複製整個文件到另一個目錄下麵,磁碟合理劃分,甚至配置IP,這些問題其實都不是很難的,只要瞭解了 Linux 的基礎 ...
  • 我的Ubuntu 預設是安裝了python2.7 和3.4 的, 這裡Django 通過 pip ( tool for installing and managing Python packages)來安裝 沒有安裝pip 的 首先安裝 pip 工具 安裝完之後 pip 線上安裝Django 連等號 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...