利用計算機運行程序大部分都是爲了提升處理效率。例如,Microsoft Word 這樣的文字處理軟件,是用來提升文本文件處理效率的程序,Microsoft Excel 等表格計算軟件,是用來提升帳本處理效率的程序。這種爲了提升特定處理效率的程序統稱爲 應用
程序員
程序員的工做就是編寫各類各樣的應用來提升工做效率,程序員通常不編寫操做系統,可是程序員編寫的應用離不開操做系統,此篇文章咱們就針對 Windows 操做系統來講明一下操做系統和應用之間的關係。數據庫
操做系統
其實也是一種軟件,任何新事物的出現確定都有它的歷史背景,那麼操做系統也不是憑空出現的,確定有它的歷史背景。編程
在計算機尚不存在操做系統的年代,徹底沒有任何程序,人們經過各類按鈕
來控制計算機,這一過程很是麻煩。因而,有人開發出了僅具備加載和運行功能的監控程序
,這就是操做系統的原型。經過事先啓動監控程序,程序員能夠根據須要將各類程序加載到內存中運行。雖然仍舊比較麻煩,但比起在沒有任何程序的狀態下進行開發,工做量獲得了很大的緩解。windows
隨着時代的發展,人們在利用監控程序編寫程序的過程當中發現不少程序都有公共的部分。例如,經過鍵盤進行文字輸入,顯示器進行數據展現等,若是每編寫一個新的應用程序都須要相同的處理的話,那真是太浪費時間了。所以,基本的輸入輸出部分的程序就被追加到了監控程序中。初期的操做系統就是這樣誕生了。服務器
相似的想法能夠共用,人們又發現有更多的應用程序能夠追加到監控程序中,好比硬件控制程序
,編程語言處理器(彙編、編譯、解析)
以及各類應用程序等,結果就造成了和如今差別不大的操做系統,也就是說,其實操做系統是多個程序的集合體。網絡
我在 程序員須要瞭解的硬核知識之CPU這篇文章中提到了彙編語言,這裏簡單再提一下。彙編語言是一種低級語言,也被稱爲
符號語言
。彙編語言是第二代計算機語言,在彙編語言中,用助記符代替機器指令的操做碼,用地址符號或標號代替指令或操做數的地址。用一些容易理解和記憶的字母,單詞來代替一個特定的指令,好比:用ADD
表明數字邏輯上的加減,MOV
表明數據傳遞等等,經過這種方法,人們很容易去閱讀已經完成的程序或者理解程序正在執行的功能,對現有程序的bug修復以及運營維護都變得更加簡單方便多線程
能夠說共用思想真是人類前進的一大步,對於解放生產力而言簡直是過重要了。編程語言
對於程序員來講,程序員創造的不是硬件,而是各類應用程序,可是若是程序員只作應用不懂硬件層面的知識的話,是沒法成爲硬核程序員的。如今培訓機構培養出了一批怎麼用的人才,卻沒有培訓出爲何這麼作的人才,畢竟爲何
不是培訓機構教的,而是學校教的,我很相信耗子叔說的話:學習沒有速成這回事。言歸正題。函數
在操做系統誕生以後,程序員不須要在硬件層面考慮問題,因此程序員的數量就增長了。哪怕自稱對硬件一竅不通
的人也可能製做出一個有模有樣的程序。不過,要想成爲一個全面的程序員,有一點須要清楚的就是,掌握硬件的基本知識,並藉助操做系統進行抽象化,能夠大大提升編程效率。性能
下面就看一下操做系統是如何給開發人員帶來便利的,在 Windows 操做系統下,用 C 語言製做一個具備表示當前時間功能的應用。time()
是用來取得當前日期和時間的函數,printf()
是把結果打印到顯示器上的函數,以下:
#include <stdio.h> #include <time.h> void main(){ // 保存當前日期和時間信息 time_t tm; // 取得當前的日期和時間 time(&tm); // 在顯示器上顯示日期和時間 printf("%s\n", ctime(&tm)); }
讀者能夠自行運行程序查看結果,咱們主要關注硬件在這段代碼中作了什麼事情
應用的可執行文件指的是,計算機的 CPU 能夠直接解釋並運行的本地代碼,不過這些代碼是沒法直接控制硬件的,事實上,這些代碼是經過操做系統來間接控制硬件的。變量中涉及到的內存分配狀況,以及 time() 和 printf() 這些函數的運行結果,都不是面向硬件而是面向操做系統
的。操做系統收到應用發出的指令後,首先會對該指令進行解釋,而後會對 時鐘IC
和顯示器用的 I/O 進行控制。
計算機中都安裝有保存日期和時間的實時時鐘(Real-time clock),上面提到的時鐘IC 就是值該實時時鐘。
操做系統控制硬件的功能,都是經過一些小的函數集合體的形式來提供的。這些函數以及調用函數的行爲稱爲系統調用
,也就是經過應用進而調用操做系統的意思。在前面的程序中用到了 time()
以及 printf()
函數,這些函數內部也封裝了系統調用。
C 語言等高級編程語言並不依存於特定的操做系統,這是由於人們但願不論是Windows
操做系統仍是 Linux
操做系統都可以使用相同的源代碼。所以,高級編程語言的機制就是,使用獨自的函數名,而後在編譯的時候將其轉換爲系統調用的方式(也有多是多個系統調用的組合)。也就是說,高級語言編寫的應用在編譯後,就轉換成了利用系統調用的本地代碼。
不過,在高級語言中也存在直接調用系統調用的編程語言,不過,利用這種方式作成應用,移植性並不友好。
移植性:移植性指的是一樣的程序在不一樣操做系統下運行時所花費的時間,時間越少證實移植性越好。
經過使用操做系統提供的系統調用,程序員沒必要直接編寫控制硬件的程序,並且,經過使用高級編程語言,有時也無需考慮系統調用的存在,系統調用每每是自動觸發的,操做系統和高級編程語言可以使硬件抽象化,這很了不得。
下面讓咱們看一個硬件抽象化的具體實例
#include <stdio.h> void main(){ // 打開文件 FILE *fp = fopen("MyFile.txt","w"); // 寫入文件 fputs("你好", fp); // 關閉文件 fclose(fp); }
上述代碼使用 C 編寫的程序,fputs()
是用來往文件中寫入字符串的函數,fclose()
是用來關閉文件的函數。
上述應用在編譯運行後,會向文件中寫入 "你好" 字符串。文件是操做系統對磁盤空間的抽象化,就如同咱們在 程序員須要瞭解的硬核知識之磁盤 這篇文章提到的同樣,磁盤就如同樹的年輪,磁盤的讀寫是以扇區爲單位的,經過磁道來尋址,若是直接對硬件讀寫的話,那麼就會變爲經過向磁盤用的 I/O 指定扇區位置來對數據進行讀寫了。
可是,在上面代碼中,扇區壓根就沒有出現過傳遞給 fopen() 函數的參數,是文件名 MyFile.txt
和指定文件寫入的 w
。傳遞給 fputs() 的參數,是往文件中寫入的字符串"你好" 和 fp,傳遞給 fclose() 的參數,也僅僅是 fp,也就是說磁盤經過打開文件這個操做,把磁盤抽象化了,打開文件這個操做就能夠說是操做硬件的指令。
下面讓咱們來看一下代碼清單中 fp 的功能,變量 fp 中被賦予的是 fopen() 函數的返回值,該值被稱爲文件指針
。應用打開文件後,操做系統就會自動申請分配用來管理文件讀寫的內存空間。內存地址能夠經過 fopen() 函數的返回值得到。用 fopen() 打開文件後,接下來就是經過制定的文件指針進行操做,正由於如此,fputs() 和 fclose() 以及 fclose() 參數中都制定了文件指針。
由此咱們能夠得出一個結論,應用程序是經過系統調用,磁盤抽象來實現對硬盤的控制的。
Windows 操做系統是世界上用戶數量最龐大的羣體,做爲 Windows 操做系統的資深
用戶,你都知道 Windows 操做系統有哪些特徵嗎?下面列舉了一些 Windows 操做系統的特性
API
函數集成來提供系統調用WYSIWYG
實現打印輸出,WYSIWYG 其實就是 What You See Is What You Get ,值得是顯示器上顯示的圖形和文本都是能夠原樣輸出到打印機打印的。這些是對程序員來說比較有意義的一些特徵,下面針對這些特徵來進行分別的介紹
這裏表示的32位操做系統表示的是處理效率最高的數據大小。Windows 處理數據的基本單位是 32 位。這與最一開始在 MS-DOS
等16位操做系統不一樣,由於在16位操做系統中處理32位數據須要兩次,而32位操做系統只須要一次就可以處理32位的數據,因此通常在 windows 上的應用,它們的最高可以處理的數據都是 32 位的。
好比,用 C 語言來處理整數數據時,有8位的 char
類型,16位的short
類型,以及32位的long
類型三個選項,使用位數較大的 long 類型進行處理的話,增長的只是內存以及磁盤的開銷,對性能影響不大。
如今市面上大部分都是64位操做系統了,64位操做系統也是如此。
Windows 是經過名爲 API
的函數集來提供系統調用的。API是聯繫應用程序和操做系統之間的接口,全稱叫作 Application Programming Interface
,應用程序接口。
當前主流的32位版 Windows API 也稱爲 Win32 API
,之因此這樣命名,是須要和不一樣的操做系統進行區分,好比最一開始的 16 位版的 Win16 API
,和後來流行的 Win64 API
。
API 經過多個 DLL 文件來提供,各個 API 的實體都是用 C 語言編寫的函數。因此,在 C 語言環境下,使用 API 更加容易,好比 API 所用到的 MessageBox()
函數,就被保存在了 Windows 提供的 user32.dll 這個 DLL 文件中。
GUI(Graphical User Interface)
指得就是圖形用戶界面,經過點擊顯示器中的窗口以及圖標等可視化的用戶界面,舉個例子:Linux 操做系統就有兩個版本,一種是簡潔版,直接經過命令行控制硬件,還有一種是可視化版,經過光標點擊圖形界面來控制硬件。
WYSIWYG 指的是顯示器上輸出的內容能夠直接經過打印機打印輸出。在 Windows 中,顯示器和打印機被認做同等的圖形輸出設備處理的,該功能也爲 WYSIWYG 提供了條件。
藉助 WYSIWYG 功能,程序員能夠輕鬆很多。最初,爲了是如今顯示器中顯示和在打印機中打印,就必須分別編寫各自的程序,而在 Windows 中,能夠藉助 WYSIWYG 基本上在一個程序中就能夠作到顯示和打印這兩個功能了。
多任務指的就是同時可以運行多個應用程序的功能,Windows 是經過時鐘分割
技術來實現多任務功能的。時鐘分割指的是短期間隔內,多個程序切換運行的方式。在用戶看來,就好像是多個程序在同時運行,其底層是 CPU 時間切片
,這也是多線程多任務的核心。
Windows 中,網絡功能是做爲標準功能提供的。數據庫(數據庫服務器)功能有時也會在後面追加。網絡功能和數據庫功能雖然並非操做系統不可或缺的,但由於它們和操做系統很接近,因此被統稱爲中間件
而不是應用。意思是處於操做系統和應用的中間層,操做系統和中間件組合在一塊兒,稱爲系統軟件
。應用不只能夠利用操做系統,也能夠利用中間件的功能。
相對於操做系統一旦安裝就不能輕易更換,中間件能夠根據須要進行更換,不過,對於大部分應用來講,更換中間件的話,會形成應用也隨之更換,從這個角度來講,更換中間件也不是那麼容易。
即插即用(Plug-and-Play)
指的是新的設備鏈接(plug) 後就能夠直接使用的機制,新設備鏈接計算機後,計算機就會自動安裝和設定用來控制該設備的驅動程序
設備驅動是操做系統的一部分,提供了同硬件進行基本的輸入輸出的功能。鍵盤、鼠標、顯示器、磁盤裝置等,這些計算機中必備的硬件的設備驅動,通常都是隨操做系統一塊兒安裝的。
有時 DLL 文件也會同設備驅動文件一塊兒安裝。這些 DLL 文件中存儲着用來利用該新追加的硬件API,經過 API ,能夠製做出運行該硬件的心應用。
文章參考:
《程序是怎樣跑起來的》第九章