日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > > strongerHuang
[導讀]關注星標公眾號,不錯過精彩內(nèi)容來源|?碼農(nóng)的荒島求生計算機系統(tǒng)中有很多程序員習以為常但又十分神秘的存在:函數(shù)調(diào)用、系統(tǒng)調(diào)用、進程切換、線程切換以及中斷處理。函數(shù)調(diào)用能讓程序員提高代碼可復用性,系統(tǒng)調(diào)用能讓程序員向操作系統(tǒng)發(fā)起請求,進程線程切換讓多任務成為可能,中斷處理能讓操作系統(tǒng)...

關注 星標公眾,不錯過精彩內(nèi)容

來源 |?碼農(nóng)的荒島求生

計算機系統(tǒng)中有很多程序員習以為常但又十分神秘的存在:函數(shù)調(diào)用、系統(tǒng)調(diào)用、進程切換、線程切換以及中斷處理。

函數(shù)調(diào)用能讓程序員提高代碼可復用性,系統(tǒng)調(diào)用能讓程序員向操作系統(tǒng)發(fā)起請求,進程線程切換讓多任務成為可能,中斷處理能讓操作系統(tǒng)管理外部設備。

這些機制是計算機系統(tǒng)中的基石,可是你知道這些機制是如何實現(xiàn)的嗎?

這篇文章將告訴你答案,其背后的實現(xiàn)如此優(yōu)雅且一致。


速度與激。。寄存器

你有沒有想過,CPU為什么需要寄存器?原因很簡單:速度。通常CPU可以在一個時鐘周期內(nèi)訪問一次寄存器,CPU訪問內(nèi)存的速度大概要比訪問寄存器慢100倍左右。因此如果CPU沒有寄存器而完全依賴內(nèi)存的話,那么計算速度將比現(xiàn)在慢的多。作為程序員來說,當我們使用高級語言編寫的程序時,其操作的數(shù)據(jù)都存放在內(nèi)存中,而對于負責運算類的機器指令來說其操作的數(shù)據(jù)都存放在寄存器中實際上寄存器和內(nèi)存沒有什么本質(zhì)的區(qū)別,都是用來存儲信息的。當然,除了臨時保存中間計算結(jié)果之外,還有很多有趣的寄存器。根據(jù)用途,寄存器有很多類型,但是,我們感興趣的有以下幾種寄存器。
棧寄存器:Stack Pointer
函數(shù)在運行時都有一個運行時棧,對于棧來說最重要的信息就是棧頂,棧頂信息就保存在棧寄存器中,stack pointer,通過該寄存器就能跟蹤函數(shù)的調(diào)用棧。最為程序員我們知道,函數(shù)在運行時會有一塊獨立的內(nèi)存空間,用來保存函數(shù)內(nèi)定義的局部變量、傳遞的參數(shù)以及返回值信息等,這塊獨立的內(nèi)存空間就叫棧幀,隨著函數(shù)調(diào)用層次的加深,棧幀也隨之增加;當函數(shù)調(diào)用完成后棧幀由按照相反的順序依次減少,這些棧幀就構(gòu)成了棧區(qū)。函數(shù)的運行時棧信息是關于程序運行狀態(tài)最重要的信息之一。那么其它的之一呢?
指令地址寄存器:Program Counter
這類寄存器的名稱比較多,基于歷史原因,大部分將其稱為Program Counter,PC,即我們熟悉的程序計數(shù)器;在x86下則被稱為Instruction Pointer,IP,怎么稱呼不重要,重要的是理解其作用。在本文中統(tǒng)一將其稱為PC寄存器。我們都知道,程序員用高級語言編寫的程序最終通過編譯器生成最終的機器指令,那么一個問題就是在茫茫的機器指令海洋中,CPU怎么知道該去執(zhí)行哪條機器指令呢?原來,奧秘就藏在指令地址寄存器中。程序在啟動時會把機器指令的首地址寫入到PC寄存器中,這樣CPU需要做的就是根據(jù)PC寄存器中的地址去內(nèi)存中取出指令。通常來說,指令都是順序執(zhí)行的,也就是說PC寄存器中的值不斷的 1,但對于一些涉及控制轉(zhuǎn)移的機器指令來說,這些指令會把一個新的指令地址放到PC寄存器中,這包括分支跳轉(zhuǎn)——也就是if語句、函數(shù)調(diào)用以及返回等。控制了CPU的PC寄存器就掌握了CPU的航向,機器指令自己會根據(jù)執(zhí)行狀態(tài)指揮CPU接下來該去執(zhí)行哪些指令,這才是真正的自動駕駛,非常amazing有沒有!指令地址寄存器是關于程序運行時狀態(tài)另一個最重要的信息之一。
狀態(tài)寄存器:Status Register
CPU內(nèi)部除了上述兩類寄存器外,還有一類狀態(tài)寄存器,Status Register;在x86架構(gòu)下被稱為FLAGS register,ARM架構(gòu)下被稱為application program status register,以下統(tǒng)稱狀態(tài)寄存器。從名字也能看出來,該寄存器是保存狀態(tài)信息的,有什么有趣的狀態(tài)信息呢?比如對于涉及到算術運算的指令來說,其在執(zhí)行過程中可能會產(chǎn)生進位,也可能會溢出,那么這些信息就保存在狀態(tài)寄存器中。除此之外,你肯定聽說過程序的執(zhí)行一般有兩種模式:內(nèi)核態(tài)和用戶態(tài)。對于大部分的程序員其編寫的應用程序運行在用戶態(tài),在用戶態(tài)下不能執(zhí)行特權(quán)指令,比如你沒辦法寫一個程序直接去控制系統(tǒng)中的各種硬件資源。而在內(nèi)核態(tài)下,CPU可以執(zhí)行任意的特權(quán)指令,內(nèi)核就工作在內(nèi)核態(tài),因此內(nèi)核可以掌控一切。關于用戶態(tài)內(nèi)核態(tài)完整的闡述參見博主深入理解操作系統(tǒng)第2章,關注公眾號碼農(nóng)的荒島求生并回復操作系統(tǒng)即可。那么我們怎么知道當前程序運行在哪種狀態(tài)呢?答案就在CPU內(nèi)部的狀態(tài)寄存器中,該寄存器中有特定的比特位來標記當前CPU正工作在哪種模式下。現(xiàn)在你應該知道寄存器的重要作用了吧。
上下文:Context
通過這些寄存器,你可以知道程序運行到當前這一刻時最細粒度的切面,這一時刻這些寄存器中保存的所有信息就是我們通常所說的上下文,context。上下文的作用是什么呢?只要你能拿到一個程序運行時的上下文并保存起來,那么你可以隨時暫停該程序的運行,也可以隨時利用該信息恢復該程序的運行。為什么要保存和恢復上下文信息呢?原因就在于CPU的個數(shù)是有限的,這就意味一個CPU可能會執(zhí)行多個進程,即這些進程要共享該CPU資源,更具體的是CPU的計算資源和這里所說的各種寄存器。這是實現(xiàn)函數(shù)調(diào)用、系統(tǒng)調(diào)用、進程切換、線程切換以及中斷處理的基本機制。而程序在運行過程中逃不出函數(shù)調(diào)用、系統(tǒng)調(diào)用、進程切換、線程切換以及中斷處理這幾項操作,由此可見上下文信息的保存和恢復在計算機科學中重要的作用。那么上下文信息又該如何保存呢?保存到哪里呢?又該怎么恢復呢?函數(shù)調(diào)用、系統(tǒng)調(diào)用、進程切換、線程切換以及中斷處理又是怎樣實現(xiàn)的呢?
游戲與棧
經(jīng)常玩游戲的同學應該都知道,游戲里有主線,有時在主線任務中還要去完成一些支線任務,也就是說任務A依賴任務B,任務B依賴任務C,那么任務的依賴關系是這樣的:
A -> B -> C那么很顯然只有完成任務C你才能繼續(xù)任務B,完成任務B才能繼續(xù)任務A,因此任務完成順序是這樣的:
C-> B -> A我們可以看到任務完成順序和任務依賴順序是相反的:先來的反而后完成這天然適合棧來表示。這里特別值得注意的是,棧是一種機制,和其本身是怎么實現(xiàn)的沒有關系,你可以用軟件來實現(xiàn)棧,也可以用硬件來實現(xiàn)棧。棧是一種如此簡單的結(jié)構(gòu),卻又如此強大。棧是實現(xiàn)計算機系統(tǒng)的一種極為重要的基礎機制,接下來的講解就能讓你意識到棧的重要作用。
函數(shù)調(diào)用與運行時棧
函數(shù)是編程語言中最重要的概念之一,函數(shù)讓代碼復用成為可能,你知道函數(shù)調(diào)用是如何實現(xiàn)的嗎?函數(shù)調(diào)用的難點在于CPU不能在平鋪直敘的往前依次順序的執(zhí)行機器指令,而是要跳轉(zhuǎn)到被調(diào)函數(shù)的第一條機器指令,執(zhí)行完該函數(shù)后還要跳轉(zhuǎn)回來。當你從A函數(shù)跳轉(zhuǎn)到B函數(shù)時,A函數(shù)被暫停運行,當被調(diào)函數(shù)執(zhí)行完后A函數(shù)繼續(xù)運行。因此這里就涉及到A函數(shù)的狀態(tài)保存與狀態(tài)恢復函數(shù)的運行時狀態(tài)有什么呢?主要有返回地址以及使用的寄存器信息,這就是在本文開頭講解的寄存器,我們將其稱為函數(shù)運行時上下文,簡稱為context。這些context保存在哪里呢?我想你已經(jīng)猜到了,沒錯,就是棧中,我們?yōu)槊總€函數(shù)分配一塊空間,當A函數(shù)調(diào)用B函數(shù)時,我們在這塊空間中保存該函數(shù)的context,當B函數(shù)執(zhí)行結(jié)束后,我們再用該context恢復A函數(shù)的運行。如果是A函數(shù)調(diào)用B函數(shù),B函數(shù)調(diào)用C函數(shù)的話,那么:這塊用來保存context的空間就是棧幀,當然這里不止保存上下文信息,還保存有函數(shù)參數(shù),局部變量等信息。從這里我們可以看到,棧 上下文讓我們實現(xiàn)了函數(shù)調(diào)用。當然限于篇幅,這里關于函數(shù)運行時棧的講解非常簡略,關于這一部分更加詳細的講解關注公眾號碼農(nóng)的荒島求生并回復關鍵詞運行時棧即可。
系統(tǒng)調(diào)用與內(nèi)核棧
當我們讀寫磁盤文件或者創(chuàng)建新的線程時,你有沒有想過到底是誰幫你讀寫的文件,是誰幫你創(chuàng)建的線程呢?答案是操作系統(tǒng)。是的,當你調(diào)用類似open這樣的函數(shù)時,其實是操作系統(tǒng)在幫你完成文件打開操作,用戶程序向操作系統(tǒng)請求服務就是通過系統(tǒng)調(diào)用實現(xiàn)的。好奇的同學可能會繼續(xù)問,既然是操作系統(tǒng)來完成這些請求,那么操作系統(tǒng)內(nèi)部肯定也是調(diào)用一系列函數(shù)來完成請求處理,有函數(shù)調(diào)用就需要運行時棧,那么操作系統(tǒng)完成系統(tǒng)調(diào)用所需要的運行時棧在哪里呢?答案就在內(nèi)核棧中,Kernel Stack。原來,每一個用戶態(tài)線程在內(nèi)核態(tài)都有一個對應的內(nèi)核棧當用戶線程需要請求操作系統(tǒng)服務時利用系統(tǒng)調(diào)用切換到內(nèi)核模式,這時內(nèi)核開始代表該用戶態(tài)線程執(zhí)行,內(nèi)核的執(zhí)行過程需要的運行時棧就放在了上圖中的內(nèi)核棧中。讓我們來看一下系統(tǒng)調(diào)用的過程。開始時,程序運行在用戶態(tài),此時內(nèi)核棧還是空的,假設用戶態(tài)執(zhí)行到functionD時需要請求操作系統(tǒng)服務,假設functionD需要調(diào)用open函數(shù),該函數(shù)內(nèi)部包含就系統(tǒng)調(diào)用,被編譯器翻譯后會生成一條int指令,此時CPU執(zhí)行到該指令:該指令的執(zhí)行將觸發(fā)CPU的狀態(tài)切換,此時CPU從用戶態(tài)切換為內(nèi)核態(tài),并找到該用戶態(tài)線程對應的內(nèi)核線程,注意重點來了,此時用戶態(tài)線程的執(zhí)行上下文信息(寄存器信息)被保存在內(nèi)核棧中:此后CPU開始在內(nèi)核中執(zhí)行open相關的操作,后續(xù)內(nèi)核棧會像用戶態(tài)運行時棧一樣隨著函數(shù)的調(diào)用和返回增長以及減少:當系統(tǒng)調(diào)用執(zhí)行完成后,根據(jù)內(nèi)核棧中保存的用戶態(tài)程序上下文信息恢復CPU狀態(tài),并從內(nèi)核態(tài)切換回用戶態(tài),這樣用戶態(tài)線程就可以繼續(xù)運行了:現(xiàn)在你應該明白這個過程了吧。那么操作系統(tǒng)為什么要這么麻煩的費心維護用戶態(tài)以及內(nèi)核態(tài)呢?用戶態(tài)程序為什么要利用系統(tǒng)調(diào)用來請求操作系統(tǒng)服務呢?不能直接像普通函數(shù)一樣調(diào)用操作系統(tǒng)的代碼嗎?關于這些問題的答案,你可以參考博主的深入理解操作系統(tǒng)第2章,關注公眾號碼農(nóng)的荒島求生并回復操作系統(tǒng)這幾個字即可。
中斷與中斷函數(shù)棧
現(xiàn)在我們已經(jīng)講解了兩種涉及CPU上下文切換的場景,包括函數(shù)調(diào)用以及系統(tǒng)調(diào)用,接下來我們再看一種,中斷處理。你的計算機之所以能接受鍵盤按鍵、鼠標指針、網(wǎng)絡數(shù)據(jù)等,都是通過中斷機制來完成的。中斷本質(zhì)上就是打斷當前CPU的執(zhí)行流,跳轉(zhuǎn)到具體的中斷處理函數(shù)中,當中斷處理函數(shù)執(zhí)行完成后再跳轉(zhuǎn)回來。既然中斷處理函數(shù)也是函數(shù),那么必然和普通函數(shù)一樣需要運行時棧,那么中斷處理函數(shù)的運行時棧又在哪里呢?這分為兩種情況:
  • 中斷處理函數(shù)是沒有自己特定的棧的,中斷處理函數(shù)依賴內(nèi)核棧來完成中斷處理。

  • 中斷處理函數(shù)有自己特定的棧,被稱之為ISR棧,ISR是interrupt service routine的簡寫,即中斷處理函數(shù)棧。由于處理中斷的是CPU,因此在這種方案下每個CPU都有一個自己的中斷處理棧。

為了簡單起見,我們以中斷處理函數(shù)共享內(nèi)核棧為例來講解。實際上你會發(fā)現(xiàn)中斷處理函數(shù)和系統(tǒng)調(diào)用比較類似,不同的是系統(tǒng)調(diào)用是用戶態(tài)程序主動發(fā)起的,而中斷處理是外部設備發(fā)起的,也就是說CPU在執(zhí)行完用戶態(tài)的任何一條指令后都可能因為中斷產(chǎn)生而暫停當前程序的執(zhí)行轉(zhuǎn)而去執(zhí)行中斷處理函數(shù),如圖所示:此后的故事和系統(tǒng)調(diào)用類似,CPU從用戶態(tài)切換為內(nèi)核態(tài),并找到該用戶態(tài)線程對應的內(nèi)核線程,并將用戶態(tài)線程的執(zhí)行上下文信息保存在內(nèi)核棧中:此后CPU跳轉(zhuǎn)到中斷處理函數(shù)起始地址,中斷處理函數(shù)在運行過程中內(nèi)核棧會像用戶態(tài)運行時棧一樣隨著函數(shù)的調(diào)用和返回增長以及減少:當中斷處理函數(shù)執(zhí)行完成后,根據(jù)內(nèi)核棧中保存的用戶態(tài)程序上下文信息恢復CPU狀態(tài),并從內(nèi)核態(tài)切換回用戶態(tài),這樣用戶態(tài)線程就可以繼續(xù)運行了。每一次你敲擊鍵盤、滑動鼠標、下載文件等都會有一次上述過程。關于中斷處理更加完整的闡述參見博主深入理解操作系統(tǒng)第3章,關注公眾號碼農(nóng)的荒島求生并回復操作系統(tǒng)即可。既然你已經(jīng)知道了中斷是如何實現(xiàn)的,接下來讓我們看下最有意思的線程切換是如何實現(xiàn)的。
線程切換與內(nèi)核棧
現(xiàn)在我們知道了每個線程除了用戶態(tài)的函數(shù)運行時棧之外還有一個我們看不見的內(nèi)核棧,系統(tǒng)調(diào)用陷入內(nèi)核后,開始將用戶態(tài)上下文信息保存在相應的內(nèi)核棧上,此后內(nèi)核代表該線程在內(nèi)核中執(zhí)行相應的操作,執(zhí)行結(jié)束后根據(jù)內(nèi)核棧上保存的上下文信息恢復用戶態(tài)線程。那么線程切換是如何實現(xiàn)的呢?線程切換是如何給CPU實施換顱術的呢?本文剩余部分已收錄至小風哥的深入理解操作系統(tǒng)第五章第四節(jié),關注公眾號碼農(nóng)的荒島求生并回復操作系統(tǒng)即可。
總結(jié)
程序的運行狀態(tài)說到底就是CPU內(nèi)部的一些寄存器信息,比如指向運行時棧頂?shù)臈<拇嫫?、指向下一條要執(zhí)行指令的PC寄存器等,這些被稱為上下文信息,能得到這些信息你就能給暫?;蛘呋貜统绦虻倪\行。上下文信息的保存與恢復通常通過棧這種機制來實現(xiàn),棧FILO的特性天然適合應對該場景,這也使得棧成為計算機系統(tǒng)中最為重要的數(shù)據(jù)結(jié)構(gòu)之一。上下文信息 棧的組合使得函數(shù)調(diào)用、系統(tǒng)調(diào)用、進程切換、線程切換以及中斷處理成為可能。------------?END?------------

后臺回復『日常記錄』『科普知識』閱讀更多相關文章。


歡迎關注我的公眾號,回復“加群”按規(guī)則加入技術交流群,回復“1024”查看更多內(nèi)容。
歡迎關注我的視頻號:


點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。

本站聲明: 本文章由作者或相關機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅(qū)動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅(qū)動性能的關鍵。

關鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質(zhì)量和效率直接關系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅(qū)動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關鍵字: LED 驅(qū)動電源 開關電源

LED驅(qū)動電源是把電源供應轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅(qū)動電源
關閉