? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?🎬慕斯主頁:修仙—別有洞天
?? ????????????????????????????????????????? ???今日夜電波:會いたい—Naomile
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1:12━━━━━━?💟──────── 4:59
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????🔄 ? ?? ? ? ? ?? ? ????
??????????????????????????????????????💗關注👍點贊🙌收藏您的每一次鼓勵都是對我莫大的支持😍
目錄
再談地址空間及物理內存
再談頁表
缺頁中斷
再次理解線程
線程的優缺點
線程的優點
線程的缺點
面試常問
?再談地址空間及物理內存
????????前面我們談到,一個可執行程序或者文件中無論他的屬性還是數據塊都是以4kb為單位進行儲存在磁盤上的(當然這個4kb這個基本單位是可以修改的!但是,這屬于特殊情況,大多數還是基本單位還是4kb),如果我們要執行某可執行程序,需要以4kb為基本單位映射到物理內存當中,再通過頁表映射到地址空間上供對應的進程進行控制。現在,我們進一步的進行理解:對此,我們將可執行程序中一個形成為4kb的大小稱為頁幀,而物理內存中也需要像exe中以4kb為基本單位來進行存儲,磁盤將exe中的頁幀映射到物理內存中,而物理內存對應的映射塊稱為頁框,exe將多少個頁幀映射到物理內存上,則物理內存就需要有多少個頁框進行承裝!如果我們要對某個文件進行修改,那么也是按這個基本單位將物理空間上以一個一個的頁框為io的基本單位刷新到磁盤上的!如下圖所示:
?
????????我們都知道inode是128b的,則一個基本單位4kb可以存儲32個inode,如果我們要訪問一個文件,我們加載inode時,可能會一次性加載多個inode。
????????前面談到了文件緩沖區的概念,這里進一步闡述,文件緩沖區實際上就是對內存當中屬于這個文件的一個個內存頁中對應的數據結構以及數據對象進行關聯。如下圖所示:
?
????????當然,我們的頁框的使用情況操作系統也是需要知道的,因此操作系統需要管理全部頁框,因此要先描述,在組織。操作系統會維護一個數據結構struct_page,這個數據結構實際上不大,大概只有10幾kb。如下:
struct page
{//描述一個page的使用情況 int flag; //用比特位來表示如正在被使用,//是否準備被釋放等等使用情況,可以用一個整數+宏來表示。//page的屬性}
????????當然,我們上面的是一個page的情況,也就是先描述,后續我們可以定義一個大的數組來組織:struct page pages[page總數] 。當然,上述只是簡化的情況,實際的數據結構會更復雜!會有內存管理的算法,比如LRU等等。對物理內存的管理,現在就變成了對于數組的增刪查改。
????????在理解了page的相關知識后,我們再次理解緩沖區的概念,我們的緩沖區真的是直接指向物理內存嗎?實際上他是指向了相關的struct page的地址或者數組下標即可。如下:
?
?
再談頁表
????????頁表實際上的結構是怎么樣的呢?虛擬地址到物理地址的轉換實際上是怎么樣的呢?CPU中有個組件MMU可以將寄存器中的虛擬地址轉換為物理地址,虛擬地址到物理地址的轉換實際上只是在CPU內部進行的。在此前我們只知道虛擬地址只是有32個比特位。如:1111 1111 1000 0000 1000 0000 0001 0001實際上會將虛擬地址按照10、10、12來劃分為三個部分。分別為頁目錄、頁表、偏移量。可以看到對應的大小為1024b、1024b、4kb。頁目錄是用于查找頁表的,他會存儲對應頁表的地址(因為具體在什么位置操作系統也不知道),然后頁表的內容會指向頁框的起始地址,也就是說頁表內存的是頁框!因此,如果我們要將虛擬內存映射到物理內存只需要頁目錄+頁表即可,也就是1024b*1024b大小,也就是2的20次方項地址。而后面的12位是可以看到是剛剛好4kb!那么我們要找到對應的物理內存只需要將頁表內的頁框地址加上對應的偏移量即可!具體的圖示如下:
?
缺頁中斷
????????通過上面對于頁表的理解,我們也理解到了通過頁目錄以及頁表就可找到對應的物理地址。但是,當我們根據局部性原理集中的訪問一段區域,后面的頁表并沒有訪問過,那么我們可以不急著創建對應的頁表,只有當要使用的時候,我們再去創建!
再次理解線程
????????再次理解了虛擬地址到物理地址的轉換后,我們在理解一個線程要劃分對應的資源時(如:代碼和數據),本質上就是在劃分頁表!
????????劃分頁表的本質:劃分地址空間!
????????劃分地址空間的例子:線程創建的接口會傳入一個函數,而這個函數經過匯編之后你會看到很多的虛擬地址,我們在申請對應的空間后會得到對應的虛擬地址,一個函數會有多行代碼,也就是說有很多的地址。定義一個變量也會有對應的地址。劃分地址空間實際上就是占有了虛擬地址上的一部分地址空間,劃分了自己的勢力范圍!
????????變量拓展:我們在定義某個類型的變量的時候互得到一個虛擬地址,但是按照對應的定義他會有幾個字節的空間,但是我們取地址又只能得到一個地址。這是因為類型的本質就是偏移量!當我們定義好一個變量時就決定了內存和CPU之間用怎么樣的寄存器來存取!
????????在進程的視角:虛擬內存本身就是資源!
線程的優缺點
線程的優點
????????創建一個新線程的代價要比創建一個新進程小得多
????????與進程之間的切換相比,線程之間的切換需要操作系統做的工作要少很多
????????線程占用的資源要比進程少很多
????????能充分利用多處理器的可并行數量
????????在等待慢速I/O操作結束的同時,程序可執行其他的計算任務
????????計算密集型應用,為了能在多處理器系統上運行,將計算分解到多個線程中實現
????????I/O密集型應用,為了提高性能,將I/O操作重疊。線程可以同時等待不同的I/O操作。
????????合理的使用多線程,能提高CPU密集型程序的執行效率????????合理的使用多線程,能提高IO密集型程序的用戶體驗(如生活中我們一邊寫代碼一邊下載開發工具,就是多線程運行的一種表現)
?
線程的缺點
性能損失
????????一個很少被外部事件阻塞的計算密集型線程往往無法與共它線程共享同一個處理器。如果計算密集型線程的數量比可用的處理器多,那么可能會有較大的性能損失,這里的性能損失指的是增加了額外的同步和調度開銷,而可用的資源不變。
健壯性降低
????????編寫多線程需要更全面更深入的考慮,在一個多線程程序里,因時間分配上的細微偏差或者因共享了不該共享的變量而造成不良影響的可能性是很大的,換句話說線程之間是缺乏保護的。
缺乏訪問控制
????????進程是訪問控制的基本粒度,在一個線程中調用某些OS函數會對整個進程造成影響。
編程難度提高
????????編寫與調試一個多線程程序比單線程程序困難得多
????????單個線程如果出現除零,野指針問題導致線程崩潰,進程也會隨著崩潰
????????線程是進程的執行分支,線程出異常,就類似進程出異常,進而觸發信號機制,終止進程,進程終止,該進程內的所有線程也就隨即退出
?
面試常問
????????線程哪部分資源是私有的?
????????一定要答到線程是有獨立的硬件上下文的(證明你是有動態切換的概念),每個線程要有自己的棧結構(證明你有動態運行的概念)。
????????更加詳細:
????????線程共享進程數據,但也擁有自己的一部分數據:
????????線程ID、一組寄存器、棧、errno、信號屏蔽字、調度優先級
?
???????????????????????感謝你耐心的看到這里?( ′・?・` )比心,如有哪里有錯誤請踢一腳作者o(╥﹏╥)o!?
????????????????????????????????? ? ? ?
????????????????????????????????????????????????????????????????????????給個三連再走嘛~??