天天看點

作業系統之程序關于程序的簡單了解

關于程序的簡單了解

  • 關于程序的簡單了解
    • 引言
    • 程序
    • 程序API
    • 關于建立程序作業系統幹了什麼
    • 程序狀态Process States

1 引言

  程序(The process)是作業系統提供給使用者最為基礎的抽象模型,我們可以簡單的定義其為:一個正在運作的程式(A running program)。而程式本身就是一堆指令的集合(還有一些靜态資料),呆在硬碟裡等待着作業系統調用這些指令資訊,讓程式跑起來,來完成我們想要的任務。

  我們知道,單程序是難以滿足使用者需求的。舉個簡單例子,平時使用者在使用電腦或者筆記本時,浏覽網頁的同時,會聽歌,會下載下傳,會收發郵件等。正是這些‘同時’運作的程序令使用者感到操作的流暢和友善。

  然而CPU其實隻有一個,這麼多程序同時運作顯然是個假象,那麼是誰給使用者制造出這種假象的?毫無疑問就是作業系統(OS)。

作業系統通過虛拟化CPU:運作一個程序,過一會将其停止,然後運作其他程序。作業系統通過這種方式制造出有很多邏輯上的CPU,而事實上真正的實體硬體隻有一個CPU而已。這種基礎技術允許使用者同時運作很多程序,我們将其稱之為CPU時間共享(Time sharing of the CPU)。當然,這種機制會導緻每個程序的運作速度變慢。

  實作虛拟化CPU,作業系統需要低層次機構(low-level machinery)和高層次政策(high-level intelligence)。低層次機構我們稱之為機制(mechanisms),為作業系統提供基本的底層基礎功能,例如上下文轉換(context switch)。高層次政策主要是一些算法讓作業系統更好的去決策。比如作業系統該運作什麼程式,該運作多長時間,這些都是由作業系統的排程政策(scheduling policy)來決定的。

2 程序

  作業系統正在運作的程式,我們稱之為程序。為了能夠更好的了解程序,我們需要了解它的機器狀态(machine state):一個程序能夠讀什麼?更新什麼?主機的哪一個部分對程序的運作起着關鍵作用?

  記憶體是構成程序機器狀态的一個關鍵内容,無論是指令還是程序運作時的讀寫資料都存儲在記憶體當中。另外,寄存器也是構成程序機器狀态的一部分,許多指令的讀取更新都是需要寄存器的參與。

3 程序API

  這裡我們來簡單了解一下關于程序的API函數,任何一個現代作業系統都包含以下功能函數。

- Create:作業系統必然可以建立新的程序。當你在shell中輸入指令或者用滑鼠輕按兩下應用圖示時,作業系統會建立相應的程序,運作相關的程式。

- Destroy:作業系統可以建立線程同樣也可以銷毀程序。當然很多時候,程序在運作完成後會自動銷毀,如果程序并沒有按預期銷毀或者使用者希望Kill掉程序,該接口是非常有用的。

- Wait:在有些情況下,一個程序需要等待其他程序停止運作。是以提供了該接口。

- Miscellaneous Control:除了殺死和等待程序等操作,這裡還有其他對程序的操作控制。比如說,很多作業系統提供類似于延緩程序的接口(終止程序的執行過一會再恢複程序執行)

- Status:還有一些API函數用于擷取程序的狀态資訊,比如程序運作了多長時間,程序目前的狀态等。

4 關于建立程序:作業系統幹了什麼

  我們來簡要描述一個程式如何轉變成一個程序的過程。當然這整個過程的操縱者便是作業系統。

  作業系統首先得将程式的源碼(code)和所有的靜态資料(static data)從磁盤(disk)載入到記憶體(memory)和程序位址空間當中。早期的作業系統是在程式運作之前将所有的代碼和資料載入到記憶體當中,而現代作業系統在程式運作時,在程式需要相關代碼和資料時,才将部分載入到記憶體當中。

  當代碼和資料加載完畢後,在運作程序之前,作業系統需要為程式的運作棧(run-time stack)申請開辟(allocate)記憶體。我們知道,C程式中的局部變量,函數參數,傳回位址等都得用到棧。這時候作業系統還會初始化相關參數,比如main()函數的argc變量和argv數組。

  作業系統還會為程式堆開辟記憶體。在C程式中,堆被用于動态申請記憶體的資料。程式中常用函數malloc()來申請空間,函數free()來用來釋放空間。一些資料結構諸如連結清單、哈希表、樹等都需要用到程式堆。程式在調用malloc()函數申請記憶體時,作業系統會參與到該過程中,開辟記憶體給程序滿足其需求。

  作業系統還會做些與輸入輸出相關初始化任務。比如,在UNIX系統中,每個程序有預設的三個檔案描述符(file descriptor):标準輸入(standard input)、标準輸出(standard output)和标準錯誤(standard error)。這些描述符可以讓程式非常友善的從終端讀入和将輸出列印到終端。

作業系統之程式關于程式的簡單了解

  在上述的準備工作完成後,作業系統已經為程式的運作做好了準備,現在最後的任務是找到main()的位址,然後開始運作程式。這時候,作業系統将CPU的控制權交給新建立的程序,程式開始執行。

5 程序狀态(Process States)

  簡單來說一個程序有以下三種狀态:-

- 運作态(running):運作态指一個程序正在處理器上運作。意思是正在執行指令。

- 就緒态(Ready):就緒态指一個程序準備好運作了,但作業系統在此刻選擇不讓該程序運作,CPU沒有配置設定過去。

- 阻塞态(Blocked):阻塞态指一個程序等待某些事件,這段期間無法運作。比如說當一個程序等待I/O操作完成的期間。這時候處理器可用于其他程序。

作業系統之程式關于程式的簡單了解

  三個狀态的關系如上圖所示,可以看到:

- 就緒态到運作态:程序被作業系統排程(schedule),配置設定CPU執行程序。

- 運作态到就緒态:程序沒有被作業系統排程(deschedule)(占用CPU時間過長或有更高優先級程序需要被執行,作業系統強迫其讓出CPU)

- 阻塞态到就緒态: I/O操作完成等

- 運作态到阻塞态:發生了I/O請求等

  最後我們來看一個例子,看看兩個程序是如何從這三種狀态變換的。如下圖所示:

作業系統之程式關于程式的簡單了解

  Process0程序的I/O事件發生時,作業系統發現Process0讓出了CPU,于是從就緒隊列中排程Process1,配置設定CPU,開始執行Process1。當Process0的I/O事件完成時,Process0将轉變成就緒态。直到Process1完成時,則Process0開始轉變運作态繼續執行,然後完成。

繼續閱讀