解说天下之操作系统
解說天下之操作系統
本文由桌案drawon?(https://www.drawon.cn),云晶(https://www.yunjingxz.com)創始人根據多年從業經驗, 從操作系統的起源,應用分類, 設計分類,以及資源使用角度對操作系統進行宏觀的闡述,通過閱讀本篇內容,您將大致對操作系統有更系統、更宏觀,更深入的認識。我們每個人每天都在高頻次的使用不同的操作系統,有必要對操作系統從宏觀,深入淺出的有一個基本的認識和了解。
前后臺系統
前后臺系統為操作系統的原古時期。 在沒有操作系統誕生之前,基本計算機系統就是前后臺系統架構模型。
前后臺系統的概念
在沒有操作系統出現之前的系統為前后臺系統,比如現在大多數嵌入式系統中所是用的MCU可以運行簡單的C語言程序的單片機在裸跑的時候,我們認為為前后臺系統,下面一張圖介紹了前后臺系統的模型:
從圖中,我們可以看到,有如下特點
應用程序是一個無限的循環, 一般在主函數中,會寫一個死循環,這個循環會有一定的延時,每隔一段時間循環執行一次。 循環中調用相應的函數,完成相應的操作, 這部分可以看成是后臺的行為(background)。無限循環掃描,就是一個輪詢 。
后臺系統,總是會運行,(The background is always running)這個Main函數是不會停止的。
當有緊急任務需要處理時, 則MCU提供一種中斷機制, 每個中斷向量掛接一個中斷處理函數, 進行緊急的處理。這種中斷處理程序的行為,我們稱之為前臺行為(Foreground)。當緊急事件發生時, 中斷處理機制會立即捕獲它。 而緊急事件,一般都是外部IO觸發, 觸發行為有高電平變低觸發,低電平變高觸發,還有上升沿或者下降沿觸發。 還有一種內部定時觸發等。
如下為前后臺系統的變成模型
{void main () {for(;;) {InitSystem();InitUartIsr(OnUartDataReceived);for(;;) {LED0 = ON;DelayMillisecs(500);LED1 = OFF;DelayMillisecs(500);}}} void OnUartDataReceived(byte[] buffer, int count) {// doing something.} }前后臺系統的優點
前后臺系統的機制相對簡單, 對編程人員要求比較低。 只要學點C語言, 了解點基礎硬件相關的知識, 就能干點事情,如點亮LED燈。燈。 可以基于單片機來學習前后臺系統。
如下推薦一些單片機的書籍, 可以借助這些書籍去學習前后臺系統。
如下為前后臺系統的優點:
- 成本低, 一般情況下, 幾毛錢,甚至幾塊錢就能買到一個單片機。
- 需求量非常大, 只要帶一些簡單的控制邏輯的系統,大多數都采用簡單的MCU, 內部運行一個前后臺系統,如下我們給出一張操作系統的分布金字塔圖。
- 設計開發編碼都比較簡單。 一般是由嵌入式工程師完成前后臺系統的開發與設計。
前后臺系統的缺點
- 應用場景比較簡單, 控制簡單的外圍電腦和簡單的運算。 對于大型復雜的邏輯或者交互,前后臺系統很難勝任。還有一些比較厲害的高人, 使用前后臺系統可以完成操作系統能夠完成的任務,甚至操作系統都難以完成的事情(小才大用)。
- 資源很難系統的調度,原地轉圈圈前后臺系統的CPU 一直都很忙,資源很難系統調度。
- 開發系統時,代碼的耦合度較高,你中有我,我中有你。前后臺系統中,每為一個系統添加一個軟件模塊,都可能影響到之前的功能。所以如果要把前后臺系統的系統玩好,一定得做到統領全局, 了解到別人的程序邏輯。
操作系統
基本概念
控制和管理計算機系統內部各種硬件和軟件資源、有效的組織多道程序運行的系統軟件(或程序集合),是用戶與計算機之間的接口。
下面分享上面上,主流的操作系統
Windows操作系統
MAC OS 操作系統
Chome OS 操作系統
移動端的IOS, Android ,Windows Phone(過去式)
操作系統,決定了系統的交互方式,以及生態,每個人,都有自己喜歡的操作系統。
操作系統分類
按照家族分類
如下為Unic的家族史:
從上圖可以看到, Unix(Unics)實際上是大部分操作系統的祖先。 很多操作系統都是從Unix演變而來。
Unix家族演進圖
從上圖可以看出:
- 目前非常著名的蘋果公司的PC領域的操作系統MAC OS以及移動端操作系統IOS均是由Unix系統改寫而來。
- 谷歌的Android操作系統,ChromeOS 均是由Linux系統修改而來。
- Ubuntu 更是Linux系統的社區開源版本。
- 還有在車載系統中,號稱是實現很強的微內核系統 QNX均來自Unix系統。
按照內核類型分類
微內核/宏內核的概念
操作系統最核心的功能,任務調度、內存和設備的抽象和管理。然后 ,為了我們方便使用,才集成進了系統服務、驅動程序、文件系統之類的東西。
我們平時運行的程序,每個程序各運行幾十毫秒,大家來回輪換,這樣子我們看起來這些程序好像在“同時”運行一樣。應用程序之所以能夠被操作系統通過時間片的方式調度,是因為對于CPU而言,普通的應用程序和操作系統的內核運行在不同的特權級別上,我們叫作rings。應用程序運行在Ring 3,而內核運行在Ring 0。
隨著科技的發展,操作系統變得越來越復雜,內核里面的東西也越來越多。人們也就開始考慮是否應該改變原有的架構,從而提高操作系統的性能和穩定性,主要是精簡內核降低開發的復雜度,還有就是把各種程序盡可能的隔離,保證一個程序的崩潰不會牽連到其他的程序。
上世紀80年代人們討論得火熱的微內核就是這樣一種架構。
幾種內核架構
理論設計,放到現實的工程中都是要做折衷的。所以有混合內核的出現,綜合宏內核和微內核的不同優點,在兩個方案中折衷設計。OS X和Windows就屬于這類。
微內核的優勢
微內核考慮在操作系統的內核中保留操作系統最基本的功能,也就是任務調度、內存和設備的抽象和管理。其他的功能全部從內核移出,放到用戶態中了實現,并以C/S模式對其他應用程序提供服務。
微內核帶來的好處主要是穩定性和實時性,即內核中模塊數量少了,結構更精簡更優化了,能夠影響內核的程序和驅動也減少了,穩定性隨之提高;另外就是實時性,內核精簡了以后,響應的時延的減小。不過并不是精簡了以后會使得性能提升,微內核使得內核中只有最關鍵的部分,其他模塊和系統功能全部作為獨立模塊放到用戶態空間中運行,功能分散了以后增加了通信的成本。不過微內核操作系統的特點尤其適合工控系統的控制,而且設計簡單,在小型的系統中有不少的應用。另外亦有不少實時操作系統是使用微內核架構設計。
總結幾句
-
Worse is better.
- 計算機領域往往經過完善設計的產品,最終結果都是失敗的。
- 像Unix贏了Multics一樣。
- Lisp(通用高級計算機程序語言)并沒有C語言流行。
- OSI的愿景最后由TCP/IP協議完成。
- 相信,國內號稱真正的云上操作系統,最終是由云晶-新一代云上操作系統來完成(開玩笑)。
- 微軟的WPF, 把MVVM設計模式運用的淋漓盡致,設計的如此純粹,并沒有流行起來。
......
-
宏內核就是一座華麗的宮殿。
-
微內核就是一座精致的小別墅。
Linux為什么不采用微內核或者混合內核模式?
理論上完美的問題在實踐過程中都會遇到各種不得不妥協的折衷。因為你制造出的東西是要部署到實際生活生產環境中使用。不是要一個只在實驗室中看起來很完美的作品。微內核的高度模塊化,自然要付出成本的,那就是增加代碼交互的冗余與效率的損耗, 而這恰恰是很大的問題。
Linus可以把這些亂七八糟的東西,全都一個人寫了,一遍寫對了,還能穩定跑起來,無bug,而我們這些渣渣,做不到,只能依靠保護模式來防止幾百個工程師寫出來的那一坨垃圾,動不動藍屏,自己弱,卻質疑天才的做法,和明知自己弱,還要模仿天才的做法,都是認不清現實的表現。
Linux本身在實現之初僅僅作為Linus一個業余項目而存在。而Monolithic Kernel由于不需要處理消息隊列等等原因從實現角度來說比Micro Kernel更為方便。
linus 這人對微內核不感興趣,這個大家都知道,只要有他在一天,kernel就不會考慮微內核化。他是一名實用主義者, 他說過一句名言:Talk is cheap. Show me the code。
Linus: "Gaah. Guys, this whole ARM thing is a fcking pain in the ass.” 推動了DeviceTree.(題外話,*霸氣)。這就是Linus這個人的張揚與灑脫的一面。 仔細體會。
按照實時性分類
按照實時性,將操作系統分為硬實時和軟實時。 那么什么優勢硬實時和軟實時,其實就是通過中斷的響應時間來衡量的。
衡量實時性的標準:
-
中斷的相應時間。
中斷的相應時間==關中斷的最長時間+保護CPU 內部寄存器的時間+進入中斷服務函數的執行時間+開始執行中斷服務例程(ISR)的第一條指令時間
-
任務的切換時間, 就是從當前任務掛起,到要切換的任務開始運行的時間。
-
一個硬實時操作系統面對變化的負載(從最小到最壞的情況)時,必須確定性地保證滿足時間要求。跟CPU強悍無關,必須時間具有確定性。
-
實時操作系統的代表
- Linux為實時操作系統的代表
- Vxworks(Wind River)為硬實時操作系統的代表。
以下表中,該處了實時操作系統的實時性對比
WxWorksuCOS-IIRT-Linux2QNX6MACosXWindowsLinux-GP 硬件平臺 MC68000 33MHz-486 60MHz-486 33MHz-486 任務切換 3.8us < 9us 不詳 12.57us 中斷響應 < 3us < 7.5us 25us 7.54us
操作系統中與編程有關的基本知識
進程線程的基本概念
- 并發和隔離。
- 程序執行的上下文(Context of Execution)
- 執行與調度的基本單位:thread
- 資源所有權:process
- 進程是資源的容器,包含(一個或)多個線程。 內核調度的基本單位是線程(不完全是)、而非進程。
- 同一進程下的各個線程共享資源(address space、open files、signal handlers,etc),但寄存器、棧、PC指針等不共享。
進程和線程到底有什么區別? 以上其實已經說了一部分, 線程是調度和執行的基本單位,最終代碼都在線程中執行。 而進程是資源的容器,包括一個或多個線程。 同一個進程下的各個線程共享資源。
如下圖為區別:
Linux的線程進程概念
Linux的線程是用戶級別的,也就是內核中不存在線程。
- 所有的線程管理都在應用層去執行。
- 內核不關心,實際上也覺察不到線程的存在。
Windows的線程進程概念
而從上圖也可以看出,Windows和Linux顯然采用不同的理念。
windows的線程是內核級別的。
- Windows是這些概念的一個例子。
- 內核維護著線程和進程的上下文。
- 調度實際上是基于線程而運行的。
進程間的通信
有了線程,進程的隔離, 就需要線程進程之間的通信機制來保證協作完成任務,共享訪問數據。
Windows進程間的通信
- 文件映射
- 共享內存
- 匿名管道(單項,一端寫,一端讀)
- 命名管道。
- 動態鏈接庫
- 遠程過程調用(可以在一臺機器內,也可以跨機器)
- UDS(Unix Domain Socket)
- 基于Windows的消息機制 ……
Linux進程間的通信
- 管道(Pipe),以及有名管道
- 信號(Signal)
- 報文(Message)隊列(消息隊列)
- 共享內存(效率最高)
- 信號量(Semaphore)
- 主要作用是進程間,以及同一進程的不同線程之間的同步手段 (UDS)Socket 套接字
以上Window和Linux雖然采用了不同的方式,概念上有所不同的方式進行進程間的通信,實際上,他們的基本原理類似。
線程間的通信
- 共享數據結構。共享內存
- 事件(Event)傳遞
- 消息隊列
- 郵箱(ucosII)
線程同步
線程同步,即當有一個線程在對內存或者外設進行操作時,其他線程都不可以對這個內存地址或者外設進行操作,直到該線程完成操作, 其他線程才可以進行操作,而其他線程又處于等待狀態,實現線程同步的方法有很多,如下。
- 一般使用信號量(Semaphore)。
- 高級語言如java 本身語言的設計 就為此考慮,如synchronized 關鍵字,wait, notify 方法。
- 可以使用Mutex。
- 臨界區對象。
信號量與互斥鎖
Semaphore(信號量,或者信號燈)
以一個停車場的運作為例。簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許其中三輛直接進入,然后放下車攔,剩下的車則必須在入口等待,此后來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知后,打開車攔,放入外面的一輛進去,如果又離開兩輛,則又可以放入兩輛,如此往復。在微觀世界里,計算機世界里,比如訪問硬盤空間,讀取數據,往往資源有限。 可以可以使用該機制,進行有效的對資源的訪問進行協調控制。
Mutex(互斥鎖)
一次只能有一個線程進入的特殊信號量。性能會比信號量好。對于某些特殊的應用場景, 一次只能有一個線程訪問,待該線程退出后,其他線程方可繼續運行。 例如操作系統的IO外設,打印機,現實生活當中的公共衛生間等等。
總結
- 上一篇: xml解析之dom、dom4j、SAX
- 下一篇: about 日问输入法