深入理解計算機系統——操作系統的抽象概念
1、操作系統
首先接著來討論 hello world 程序的例子。當外殼載入和運行 hello 程序,以及 hello 程序輸出自己的消息時,外殼和 hello 程序都沒有直接訪問鍵盤、顯示器、磁碟或者主存。取而代之的是,它們依靠操作系統提供服務。
那麼什麼是操作系統呢?我們可以把操作系統看成應用程序和硬體之間插入的一層軟體,如下圖:
如圖可知:所有的應用程序對硬體的操作都必須通過操作系統。常見的操作系統比如windows、Unix、Linux等等。
操作系統的兩個基本功能:
①、防止硬體被失控的應用程序濫用。
②、嚮應用程序提供簡單一致的機制來控制複雜而又大相徑庭的低級硬體設備。
我們可以通過進程、虛擬存儲器和文件這幾個抽象概念來實現上面兩個功能。
如上圖:文件是對I/O設備的抽象表示,虛擬存儲器是對主存和磁碟I/O設備的抽象表示,進程則是對處理器、主存和I/O設備的抽象表示。下面我們分別對其進行介紹。
2、進程
當我們去運行 hello 程序的時候,操作系統會給我提供一種假象,就好像系統只有這個程序在運行。處理器看上去就像在不間斷的一條接著一條地執行程序中的命令,即該程序的代碼和數據是系統存儲器中唯一的對象。
這其實是一種假象,而這種假象是通過進程的概念來實現的。
進程是操作系統對一個正在運行的程序的一種抽象,在一個系統上可以運行多個進程,而每個進程都好像在獨佔的使用硬體。但實際上,他們是並發的在運行,即一個進程的指令和另一個進程的指令是交錯運行的。
在單CPU系統中,系統在一個時刻只能運行一個進程,多CPU系統中,系統則是能夠同時處理多個進程。但無論是單核還是多核,一個CPU只能並發的執行多個進程,這是通過處理器在進程間切換來實現的。而操作系統實現這種交錯機制稱為上下文切換。
上下文:操作系統保持跟蹤進程運行所需的所有狀態信息,比如PC和寄存器文件的當前值,主存的內容。
比如上面的A進程是外殼進程,B進程是hello進程。起初只有外殼進程在運行,即等待命令行上的輸入,當我們輸入相關命令讓它運行hello程序時,外殼通過調用一個專門的函數,即系統調用,來執行我們的請求,系統會將控制權傳遞給操作系統。操作系統保存外殼程序的上下文,創建一個新的 hello 進程以及上下文,然後將控制權傳遞給新的 hello 進程。hello 進程終止後,操作系統恢復外殼進程的上下文,並將控制權回傳給它,外殼程序將繼續等待下一個命令行輸入。
實現進程這種抽象概念需要低級硬體和操作系統軟體之間的緊密合作,這個實現原理以及應用程序如何創建和控制它們的進程的呢?作為程序員的角度,這裡我們講一下,一個進程實際上是由多個稱為線程的執行單位構成,每個線程都運行在進程的上下文中,並共享同樣的代碼和全局數據,多線程比進程高效,多線程更容易共享數據。如何並發編程提高程序效率的要點後面我們會詳細講解。
3、虛擬存儲器
虛擬存儲器是一個抽象概念,它為每個進程提供了假象,即每個進程都在獨佔的使用主存。每個進程看到的是一致的存儲器,稱為虛擬地址空間。下圖是 Linux 進程的虛擬地址空間(其他Unix 系統設計類似):
在Linux系統中,地址空間最上面的區域是為操作系統中的代碼和數據保留的,這對所有進程是一致的。地址空間的底部區域存放用戶進程定義的代碼和數據。上圖的地址從下往上是增大的。
我們從最低的地址,逐步向上介紹上面出現的區域名詞。
①、程序代碼和數據:對於所有進程來說,代碼是從同一固定地址開始的,分別為0x08048000(32位)以及0x00400000(64位),緊接著是全局變數相對應的數據位置。
②、堆:代碼和數據區後緊隨的是運行時堆。代碼和數據區是在進程一開始運行時就規定了大小,而當調用malloc和free這樣的 C 標準庫函數 時,堆可以在運行時動態的擴展和收縮。
③、共享庫:存放像C標準庫和資料庫這樣的代碼和數據的區域。
④、棧:位於用戶虛擬地址空間頂部,編譯器用它來實現函數調用,用戶棧在程序執行期間可以動態的擴展和收縮。當我們調用一個函數時,棧會增長;從一個函數返回時,棧會收縮。
⑤、內核虛擬存儲器:內核總是駐留在內存中,是操作系統的一部分,不允許應用程序讀寫這個區域的內容或者直接調用內核代碼定義的函數。
關於所有進程代碼是從同一固定地址開始的,這裡我們做個驗證,我們在 Linux 64位系統上,在存放hello.c程序的目錄下輸入如下命令:運行前面寫好的 hello.c 程序,並查看地址信息
1gcc -Wl,--verbose hello.c
4、文件
文件就是位元組序列,即由值0和值1組成的序列。所有的I/O設備,包括磁碟、鍵盤、滑鼠、顯示器都可以看成是文件。
文件這個簡單而精緻的概念嚮應用程序提供了一個統一的視覺來看待系統中所有的I/O設備。這帶來的好處顯而易見,比如同一個程序可以使用不同磁碟技術的不同系統運行。
5、計算機系統中抽象的重要性
抽象的使用是計算機科學中最重要的概念之一。例如,為一組函數規定一個簡單的應用程序介面API就是一個很好的編程習慣。程序員無需了解它內部的工作原理便可以使用這些代碼。這在Java當中的典型比如類的定義,C語言中的函數原型。
6、本章總結
本章主要介紹了抽象概念在計算機系統中的重要性以及操作系統的抽象概念,包括進程、虛擬存儲器以及文件。
那麼深入理解計算機系統第一章計算機系統的漫遊將到此結束。如果又不太理解的也沒關係,畢竟前面講的都是一些概念,後面我們將會詳細講解。而下一章信息的表示和處理,可能是與我們日常編碼最相近的東西,各種數據類型在計算機總是如何存儲,它們之間做運算會有什麼意想不到的結果等等。如果好好理解了,相信在後面的編碼會更加得心應手。
文章摘自博客園
中公優就業 幫你成就職業夢:
IT教育專業培訓:https://www.ujiuye.com/
IT職業在線教育:https://xue.ujiuye.com/
大數據時代下做java開發工程師:https://www.ujiuye.com/zt/java/?wt.bd=lsh11tt
※你之所以不優秀,是因為你只走容易的路
※這些書不用藏在課本下看!
※那些年 藏在課本下的雜誌
※JAVA 線程的幾種狀態
TAG:IT優就業 |