牆上時鐘時間 ,用戶cpu時間 ,系統cpu時間內,核態和用戶態的區別

時鐘時間(牆上時鐘時間wall clock time):從進程從開始運行到結束,時鐘走過的時間,這其中包含了進程在阻塞和等待狀態的時間。
用戶CPU時間:就是用戶的進程獲得了CPU資源以後,在用戶態執行的時間。
系統CPU時間:用戶進程獲得了CPU資源以後,在內核態的執行時間。

   進程的三種狀態爲阻塞、就緒、運行。

   時鐘時間 = 阻塞時間 + 就緒時間 +運行時間
   用戶CPU時間 = 運行狀態下用戶空間的時間

   系統CPU時間 =  運行狀態下系統空間的時間。


   用戶CPU時間+系統CPU時間=運行時間。

任一進程都可以調用times函數獲取它自己以及已經終止子進程的上述值.

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. #include <sys/times.h>  
  2.   
  3. clock_t times(struct tms *buf);//返回值:若成功,返回流逝的牆上時鐘時間(以時鐘滴答數爲單位);若出錯,返回-1.  

其中buf指向tms結構:

struct tms {

clock_t tms_utime; /* 用戶CPU時間 */

clock_t tms_stime; /* 系統CPU時間 */

clock_t tms_cutime; /* 已終止子進程的用戶CPU時間 */

clock_t tms_cstime; /* 已終止子進程的系統CPU時間 */

};

注意此結構並沒有牆上時鐘值,而是返回值作爲牆上時鐘,並以滴答數爲單位.這裏返回值是想對於過去的某一時刻度量的,需要拿新返回值減去以前的返回值.如果要轉換爲秒的話需要除以每秒時鐘滴答數(這個用sysconf(_SC_CLK_TCK)可以獲取).


那麼這裏有個問題:什麼是用戶態執行時間? 什麼是內核態執行時間?

這裏參考一篇博客,講的比較清楚~

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. void testfork(){  
  2. if(0 = = fork()){  
  3. printf(“create new process success!\n”);  
  4. }  
  5. printf(“testfork ok\n”);  
  6. }  

本來打算提煉一下的,還是原文比較全面,一塊粘貼過來了,感謝原作者!

原文地址:http://www.cnblogs.com/viviwind/archive/2012/09/22/2698450.html

這段代碼很簡單,從功能的角度來看,就是實際執行了一個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種方式是系統在運行時由用戶態轉到內核態的最主要方式,其中系統調用可以認爲是用戶進程主動發起的,異常和外圍設備中斷則是被動的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章