本文將介紹一系列與Linux系統編程有關的概念。
操作系統的核心——內核
操作系統 System 、內核 kernel
-
廣義指完整的軟件包,這包括用來管理計算機資源的核心層軟件,以及附帶的所有標准軟件工具,諸如命令行解釋器、圖形用戶界面、文件操作工具和文本編輯器等。
-
狹義指管理和分配計算機資源(即CPU、RAM和設備)的核心層軟件。
術語“內核“通常是第二種含義,"操作系統”一般也是這層意思。
內核為管理計算機的有限資源所提供了軟件層。
內核的職責
- 進程調度:每個進程都能獲得對CPU的使用權。但是哪些進程能獲得對CPU的使用,使用多長時間,這些都由內核進程調度程序(而非進程本身)決定。
- 內存管理:物理內存(RAM)屬於有限資源,內核必須公平、高效地方式在進程間共享這一資源。
- 文件系統:內核在磁盤之上提供有文件系統,允許對文件執行創建、獲取、更新以及刪除等操作。
- 創建和終止進程:內核可將新程序載入內存(創建進程),為其提供運行所需的資源(比如CPU、內存以及對文件的訪問等)。這樣一個運行中的程序我們稱之為“進程”。一旦進程執行完畢,內核還要確保釋放其占用資源(終止進程),以供后續程序重新使用。
- 對設備的訪問:計算機外接設備(鼠標、鍵盤、磁盤和磁帶驅動器等)可實現計算機與外部世界的通信,這一通信機制包括輸入、輸出或是兩者兼而有之。內核既為程序訪問設備提供了簡化版的標准接口,同時還要仲裁多個進程對每一個設備的訪問。
- 聯網:內核以用戶進程的名義收發網絡消息(數據包)。該任務包括將網絡數據包路由至目標系統。
- 提供系統調用應用編程接口(API):進程可利用內核入口點(也稱為系統調用)請求內核去執行各種任務。
- 多用戶使用:每個用戶都可以登陸進行系統,獨立操作,而與其他用戶大致無干。內核負責解決(多進程)訪問硬件資源時可能引發的沖突,而用戶和進程不需要關心。
內核態和用戶態
現代處理器架構一般允許CPU至少在兩種不同狀態下運行,即:用戶態和核心態(有時也稱之為監管態)
-
用戶態 User mode
CPU只能訪問被標記為用戶空間的內存,試圖訪問屬於內核空間的內存會引發硬件異常。
-
內核態 kernel mode
當運行於核心態時,CPU既能訪問用戶空間內存,也能訪問內核空間內存。
只有當處理器在核心態運行時,才能執行某些特定操作,比如宕機(halt)指令去關閉系統,訪問內存管理硬件,以及設備I/O操作的初始化等。這確保了用戶進程既不能訪問內核指令和數據結構,也無法執行不利於系統運行的操作。
以進程及內核視角檢視系統
在完成諸多日常編程任務時,程序員們習慣於以面向進程(process-oriented)的思維方式來考慮編程問題。然而為了更高視角看問題,有必要轉換視角,站在內核的角度上來看問題。
對進程來說,許多事件的發生都無法預期。
- 進程不清楚自己在RAM中的位置。或者換種更通用的說法,進程內存空間的某塊特定部分如今到底是駐留在內存中還是被保存在交換空間里,進程本身並不知曉。
- 與之類似,進程也鬧不清自己所訪問的文件“居於“磁盤驅動器的何處,只是通過名稱來引用文件而已。
- 進程的運作方式堪稱“與世隔絕“,進程本身無法創建出新進程,哪怕“自行了斷”都不行。
- 最后還有一點,進程也不能與計算機外接的輸入輸出設備直接通信。
內核則是運行系統的中樞所在,對於系統的一切無所不知、無所不能,為系統上所有進程的運行提供便利。
-
由哪個進程來接掌對CPU的使用,何時“接任“,“任期“多久,都由內核說了算。
-
在內核維護的數據結構中,包含了與所有正在運行的進程有關的信息。隨着進程的創建、狀態發生變化或者終結,內核會及時更新這些數據結構。
-
內核所維護的底層數據結構可將程序使用的文件名轉換為磁盤的物理位置。
-
此外,每個進程的虛擬內存與計算機物理內存及磁盤交換區之間的映射關系,也在內核維護的數據結構之列。
-
進程間的所有通信都要通過內核提供的通信機制來完成。
-
響應進程發出的請求,內核會創建新的進程,終結現有進程。
-
最后,由內核(特別是設備驅動程序)來執行與輸入/輸出設備之間的所有直接通信,按需與用戶進程交互信息。
shell
shell是一種具有特殊用途的程序,主要用於讀取用戶輸入的命令,並執行相應的程序以響應命令。有時,人們也稱之為命令解釋器。
術語登錄shell(login shell)是指用戶剛登錄系統時,由系統創建,用以運行shell的進程。對UNIX系統而言,shell只是一個用戶進程。
縱觀UNIX歷史,出現過以下幾種重要的shell。
- Bourne shell:這款由Steve Bourne 編寫的shell歷史最為悠久,且應用廣泛,曾是第七版UNIX的標配shell。Bourne shell包含了在其他shell中常見的許多特性:I/O重定向、管道、文件名生成(通配符)、變量、環境變量處理、命令替換、后台命令執行以及函數。對於所有第七版UNIX之后的系統而言,除了可能提供有其他shell之外,都附帶了Bourne shell。
- C shell (csh):由Bill Joy於加州大學伯克利分校編寫而成。其命名則源於該腳本語言的流控制語法與C語言有着許多相似之處。C shell當時提供了若干極為實用的交互式特性,並不為Bourne shell所支持,這其中包括命令的歷史記錄、命令行編輯功能、任務控制和別名等。C shell與Bourne shell並不兼容。盡管C shell曾是BSD系統標配的交互式shell,但一般情況下,人們還是喜歡針對Bourne shell編寫shell腳本,以便其能夠在所有UNIX實現上移植。
- Korn shell (ksh) : AT&T貝爾實驗室的David Korn編寫了這款shell, 作為Bourne shell的“繼任者”。在保持與Bourne shell兼容的同時,Korn shell還吸收了那些與Cshell 相類似的交互式特性。
- Bourne again shell (bash):這款shell是GNU項目對Bourne shell的重新實現。Bash提供了與Cshell和Korn shell 所類似的交互式特性。Brian Fox和ChetRamey是bash的主要作者。bash或許是Linux上應用最為廣泛的shell了。在Linux上,Bourne shell (bash)其實正是由bash仿真提供的。
- Z shell(Zsh):是一款可用作交互式登錄的shell及腳本編寫的命令解釋器。Zsh對Bourne shell做出了大量改進,同時加入了Bash、ksh及tcsh的某些功能。自2019年起,macOS的預設Shell已從Bash改為Zsh。
