操作系统原理第八章:内存管理
目錄
- 1 內(nèi)存管理背景
- 2 固定分區(qū)分配
- 3 動(dòng)態(tài)內(nèi)存分配
- 3.1 首先適應(yīng) (First-fit)
- 3.2 最佳適應(yīng) (Best-fit)
- 3.3 外碎片問題
- 4 分頁(yè)
- 5 分頁(yè)硬件支持
- 6 分段管理
1 內(nèi)存管理背景
下圖是計(jì)算機(jī)系統(tǒng)中存儲(chǔ)層次結(jié)構(gòu):
本文主要討論的是其中的 主存 (primary storage) 部分。計(jì)算機(jī)程序在執(zhí)行過程中,所有程序必需放入內(nèi)存并放入一個(gè)進(jìn)程才能被執(zhí)行,程序是磁盤中的一個(gè)靜態(tài)的實(shí)體,通常對(duì)應(yīng)著一個(gè)文件,所以的程序都是在輸入隊(duì)列中等待的,所謂輸入隊(duì)列就是磁盤上等待進(jìn)入內(nèi)存并執(zhí)行的進(jìn)程的集合。用戶程序在執(zhí)行之前必需經(jīng)歷很多步驟,這里可以以C語(yǔ)言為例參考我的這篇文章 C語(yǔ)言-用gcc指令體驗(yàn)C語(yǔ)言編譯過程,如下圖所示:
在程序裝入內(nèi)存中,存在著邏輯地址到物理地址的映射問題,即在邏輯地址中x的地址是200,但在物理地址中x的地址是1200,因?yàn)閷?shí)際內(nèi)存中不可能都是從地址0開始的,如下圖:
因此需要地址之間的綁定以便于指令能夠找到實(shí)際的物理地址,指令和數(shù)據(jù)綁定到內(nèi)存地址可以在三個(gè)不同的階段發(fā)生:
- 編譯時(shí)期:如果內(nèi)存位置已知,可生成絕對(duì)代碼;如果開始位置改變,需要重新編譯代碼;
- 裝入時(shí)期:如果存儲(chǔ)位置在編譯時(shí)不知道,則必須生成可重定位代碼,實(shí)際上進(jìn)程在內(nèi)存中是不可以移動(dòng)的,若要移動(dòng)進(jìn)程則需要重新定位;
- 執(zhí)行時(shí)期:如果進(jìn)程在執(zhí)行時(shí)可以在內(nèi)存中移動(dòng),則地址綁定要延遲到運(yùn)行時(shí)。需要硬件對(duì)地址映射的支持,例如基址和限長(zhǎng)寄存器。
下圖是三種綁定階段的示例圖。在編譯時(shí)綁定,則在編譯后就明確指出操作的物理地址,即move 1156 3表示把count的值放到地址為1156的位置;在加載時(shí)綁定,則在編譯后就明確指出操作的邏輯地址,即move 156 3,在加載到內(nèi)存后進(jìn)行變換,變換到1156的位置;在運(yùn)行時(shí)綁定,則在編譯后也是只能給出邏輯地址,在加載到內(nèi)存時(shí),依然保存的是邏輯地址,但是當(dāng)執(zhí)行到這條語(yǔ)句時(shí),再執(zhí)行該指令的地址變換1000+156=1156。
上文所提及的邏輯地址和物理地址兩個(gè)概念會(huì)貫穿于整個(gè)內(nèi)存管理內(nèi)容中,他們的定義如下:
- 邏輯地址:由CPU產(chǎn)生;也叫做虛擬空間;
- 物理地址:內(nèi)存設(shè)備所讀入的地址。
在上面的圖中,指令move 1156 3中的1156就是邏輯地址,內(nèi)存中的1156地址塊就是物理地址,可以發(fā)現(xiàn)在編譯時(shí)綁定和加載時(shí)綁定中,邏輯地址和物理地址是相同的,但在運(yùn)行時(shí)綁定中,邏輯地址和物理地址是不同的。
我們把將程序裝入到與其地址空間不一致的物理空間,所引起的一系列地址變換過程叫做地址重定位,地址重定位分為如下兩種:
- 靜態(tài)地址重定位:在裝入一個(gè)作業(yè)時(shí),把作業(yè)中的指令地址全部轉(zhuǎn)換為絕對(duì)地址,在作業(yè)執(zhí)行過程中就無須再進(jìn)行地址轉(zhuǎn)換工作,如下圖:
- 動(dòng)態(tài)地址重定位:動(dòng)態(tài)地址重地位是在程序執(zhí)行過程中,在CPU訪問內(nèi)存之前,將要訪問的程序或數(shù)據(jù)地址轉(zhuǎn)換成內(nèi)存地址。動(dòng)態(tài)重定位依靠硬件地址變換機(jī)構(gòu)完成,如下圖:
通過硬件把虛擬地址映射到物理地址,所需的硬件叫做內(nèi)存管理單元(MMU),在MMU策略中,基址寄存器中的值被加入到用戶進(jìn)程所產(chǎn)生的每個(gè)地址中,在其送入內(nèi)存的時(shí)候,用戶程序所對(duì)應(yīng)到的是邏輯地址,物理地址對(duì)它從來都不可見,如下圖:
2 固定分區(qū)分配
上一節(jié)中講的主要內(nèi)容是如何把程序放入內(nèi)存,即要實(shí)現(xiàn)邏輯地址到物理地址的映射,使之能夠正確的運(yùn)行,這一節(jié)所講的主要內(nèi)容是研究放入內(nèi)存后如何給它分配內(nèi)存空間,通常來說會(huì)為一個(gè)程序分配一段連續(xù)的內(nèi)存空間,主要有:
- 單一連續(xù)區(qū)管理方式:主要針對(duì)單道批處理系統(tǒng),只有一個(gè)作業(yè)進(jìn)入內(nèi)存,內(nèi)存被分為兩塊,一塊用來存放操作系統(tǒng),一塊用來存放用戶程序,我們只要保證用戶程序不會(huì)影響到操作系統(tǒng)即可,使用基址寄存器策略來保護(hù)用戶進(jìn)程(同其他進(jìn)程和改變的操作系統(tǒng)代碼和數(shù)據(jù)分開),基址寄存器包含最小物理地址的值,即起始地址;限長(zhǎng)寄存器包含邏輯地址的范圍,每個(gè)邏輯地址必需比限長(zhǎng)寄存器的值小,即不能地址越界,判斷地址合法流程圖如下:
- 多分區(qū)管理方式:是一種可用于多道程序的較簡(jiǎn)單的存儲(chǔ)管理方式,它又分為固定分區(qū)方式和可變分區(qū)方式。
對(duì)于固定分區(qū)分配方式,固定式分區(qū)是在作業(yè)裝入之前,內(nèi)存就被劃分成若干個(gè)固定大小的連續(xù)分區(qū),劃分工作可以由系統(tǒng)管理員完成,也可以由操作系統(tǒng)實(shí)現(xiàn),一旦劃分完成,在系統(tǒng)運(yùn)行期間不再重新劃分,即分區(qū)的個(gè)數(shù)不可變,分區(qū)的大小不可變,所以,固定式分區(qū)又稱為靜態(tài)分區(qū)劃分分區(qū)的方法如下:
- 分區(qū)大小相等:比如有100MB內(nèi)存,分五個(gè)分區(qū),每個(gè)分區(qū)20MB,只適用于多個(gè)相同程序的并發(fā)執(zhí)行(處理多個(gè)類型相同的對(duì)象),缺乏靈活性,會(huì)造成內(nèi)碎片問題;
內(nèi)碎片:比如一個(gè)分區(qū)大小是20MB,但是進(jìn)程只需要16MB,多出的4MB用不上,而別的進(jìn)程也無法使用,這4MB大小的空間就叫做內(nèi)碎片。
- 分區(qū)大小不等:多個(gè)小分區(qū)、適量的中等分區(qū)、少量的大分區(qū)。根據(jù)程序的大小,分配當(dāng)前空閑的、適當(dāng)大小的分區(qū),兩種劃分方法示意圖如下圖所示:
一般將內(nèi)存的用戶區(qū)域劃分成大小不等的分區(qū),可適應(yīng)不同大小的作業(yè)的需要。當(dāng)作業(yè)到來時(shí),系統(tǒng)有一張分區(qū)說明表,每個(gè)表目說明一個(gè)分區(qū)的大小、起始地址和是否已分配的使用標(biāo)志,分區(qū)說明表和內(nèi)存分配圖如下圖所示:
總結(jié)來說固定分區(qū)分配的優(yōu)點(diǎn)是易于實(shí)現(xiàn),開銷小;缺點(diǎn)是分區(qū)大小固定,會(huì)造成內(nèi)碎片問題,同時(shí)由于分區(qū)總數(shù)固定,會(huì)限制并發(fā)執(zhí)行的進(jìn)程數(shù)目。
3 動(dòng)態(tài)內(nèi)存分配
在動(dòng)態(tài)分區(qū)分配中,分區(qū)的劃分是動(dòng)態(tài)的,不是預(yù)先確定的,當(dāng)某個(gè)進(jìn)程到來,它需要多少內(nèi)存就給它分配多少內(nèi)存,所以造成不同大小的分區(qū)分布在整個(gè)內(nèi)存中,分配過程如下圖:
在這種方式下,操作系統(tǒng)也是需要知道內(nèi)存的狀態(tài)的,可以采用空閑分區(qū)表和空閑分區(qū)鏈兩種方式,如下圖:
在可變分區(qū)分配時(shí)要設(shè)計(jì)分區(qū)分配算法來尋找某個(gè)空閑分區(qū),其大小需大于或等于程序的要求。若是大于要求,則將該分區(qū)分割成兩個(gè)分區(qū),其中一個(gè)分區(qū)為要求的大小并標(biāo)記為“占用”,而另一個(gè)分區(qū)為余下部分并標(biāo)記為“空閑”。分區(qū)的先后次序通常是從內(nèi)存低端到高端。同時(shí)也要設(shè)計(jì)分區(qū)釋放算法把相鄰的空閑分區(qū)合并成一個(gè)空閑分區(qū)。(這時(shí)要解決的問題是:合并條件的判斷)。
那么怎樣從一個(gè)空的分區(qū)序列中滿足一個(gè)申請(qǐng)需要?有如下三種方式:
- 首先適應(yīng) (First-fit):分配最先找到的合適的分區(qū);
- 最佳適應(yīng) (Best-fit):搜索整個(gè)序列,找到適合條件的最小的分區(qū)進(jìn)行分配;
- 最差適應(yīng) (Worst-fit):搜索整個(gè)序列,尋找最大的分區(qū)進(jìn)行分配。
很顯然,在速度和存儲(chǔ)的利用上,首先適應(yīng)和最佳適應(yīng)要比最差適應(yīng)好。
3.1 首先適應(yīng) (First-fit)
首先適應(yīng)的思想是從空閑分區(qū)表的第一個(gè)表目開始查找,把找到的第一個(gè)滿足要求的空閑區(qū)分配給作業(yè),目的在于減少查找時(shí)間。通常將空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按地址由低到高進(jìn)行排序,它有如下特點(diǎn):
- 分配和釋放的時(shí)間性能較好,較大的空閑分區(qū)可以被保留在內(nèi)存高端;
- 隨著低端分區(qū)不斷劃分而產(chǎn)生較多小分區(qū),每次分配時(shí)查找時(shí)間開銷會(huì)增大;
- 在系統(tǒng)不斷地分配和回收中,必定會(huì)出現(xiàn)一些不連續(xù)的小的空閑區(qū),稱為外碎片。雖然可能所有碎片的總和超過某一個(gè)作業(yè)的要求,但是由于不連續(xù)而無法分配。
外碎片:比如一塊內(nèi)存中依次分配了三個(gè)進(jìn)程 P1P_1P1?,P2P_2P2?,P3P_3P3?,其中 P2P_2P2? 占 20MB,此時(shí) P2P_2P2? 運(yùn)行結(jié)束了,釋放掉了自己的內(nèi)存,然后來了一個(gè)新進(jìn)程 P4P_4P4?,P4P_4P4? 需要 18MB 的內(nèi)存,恰好剛剛釋放掉了 P2P_2P2? 的20MB內(nèi)存可以存放,但是會(huì)有 P4P_4P4? 和 P3P_3P3? 之間會(huì)有一個(gè) 2MB 的內(nèi)存,由于它太小了,很難分配到它,所以這 2MB 內(nèi)存就叫做外碎片。
3.2 最佳適應(yīng) (Best-fit)
最佳適應(yīng)的思想是從全部空閑區(qū)中找出能滿足作業(yè)要求的、且最小的空閑分區(qū),能使碎片盡量小。為了提高查找效率,空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按從小到大進(jìn)行排序, 自表頭開始查找到第一個(gè)滿足要求的自由分區(qū)分配,它有如下特點(diǎn):
- 從個(gè)別來看,外碎片較小,但從整體來看,會(huì)形成較多無法利用的碎片;
- 較大的空閑分區(qū)可以被保留。
下面是一個(gè)具體的例子,加入要分配一個(gè)16KB分區(qū):
3.3 外碎片問題
在可變分區(qū)系統(tǒng)不斷地分配和回收中,必定會(huì)出現(xiàn)一些不連續(xù)的小的空閑區(qū),稱為外碎片。雖然可能所有碎片的總和超過某一個(gè)作業(yè)的要求,但是由于不連續(xù)而無法分配。解決碎片的方法是拼接(或稱緊湊),即向一個(gè)方向(例如向低地址端)移動(dòng)已分配的作業(yè),使那些零散的小空閑區(qū)在另一方向連成一片,但分區(qū)的拼接技術(shù),一方面要求能夠?qū)ψ鳂I(yè)進(jìn)行動(dòng)態(tài)重定位,另一方面系統(tǒng)在拼接時(shí)要耗費(fèi)較多的時(shí)間,下圖是一個(gè)拼接的例子,存在著400K,300K,200K三個(gè)外碎片,可以將其朝高地址拼接,也可以移動(dòng)某個(gè)進(jìn)程,也可以在中間拼接:
4 分頁(yè)
上面所提到的用拼接解決外碎片問題在實(shí)現(xiàn)的時(shí)候還是有很多障礙的,我們需要思考還有沒有別的方法來解決外碎片問題,我們首先來看動(dòng)態(tài)分區(qū)產(chǎn)生外碎片的原因是什么?這是因?yàn)檫@種分配要求把作業(yè)必須安置在一連續(xù)存儲(chǔ)區(qū)內(nèi)的緣故;那么如果允許物理地址空間非連續(xù),是否可以解決?分頁(yè)存儲(chǔ)管理是解決存儲(chǔ)碎片的一種方法,要避開連續(xù)性要求,允許進(jìn)程的物理地址空間不連續(xù)。
分頁(yè)的基本思想是進(jìn)程的物理地址空間可以是不連續(xù)的,如果有可用的物理內(nèi)存,它將分給進(jìn)程。我們把物理內(nèi)存分成大小固定的塊。把邏輯內(nèi)存也分為固定大小的塊,叫做頁(yè),要求頁(yè)的大小和塊的大小是一樣的,如下圖所示:
根據(jù)上圖可以看出,把邏輯內(nèi)存劃分為塊之后,可以離散的分布在物理內(nèi)存中。當(dāng)然在這種情況下,操作系統(tǒng)需要知道哪些頁(yè)是空閑的,運(yùn)行一個(gè)有N頁(yè)大小的程序,需要找到N個(gè)空的頁(yè)框讀入程序,還要解決的問題就是邏輯地址到物理地址的映射,我們是通過建立一個(gè)頁(yè)表,把邏輯地址轉(zhuǎn)換為物理地址。此外,由于內(nèi)存塊的劃分是采用固定大小分配的,所以不可避免的會(huì)在最后一個(gè)頁(yè)中產(chǎn)生內(nèi)碎片,地址映射如下圖所示:
我們知道由CPU產(chǎn)生的地址是邏輯地址,CPU 產(chǎn)生的地址被分為:
- 頁(yè)號(hào) p (Page number):它包含每個(gè)頁(yè)在物理內(nèi)存中的基址,用來作為頁(yè)表的索引,也就是一個(gè)程序會(huì)被劃分為多個(gè)塊,對(duì)應(yīng)在物理地址中是多個(gè)頁(yè),頁(yè)號(hào)指明了具體是哪個(gè)頁(yè);
- 偏移 d (Page offset):同基址相結(jié)合,用來確定送入內(nèi)存設(shè)備的物理內(nèi)存地址,也就是一個(gè)頁(yè)內(nèi)有很多地址,偏移是確定具體是哪個(gè)地址。
通過頁(yè)號(hào)和偏移確定物理地址的過程如下圖,通過頁(yè)號(hào) p 去查找頁(yè)表 page table,找到在頁(yè)表中的哪個(gè)頁(yè) f,然后把 f 取出來再加上偏移 d,就可以映射到所在的物理地址:
總結(jié)來說分頁(yè)解決了外碎片問題,但是會(huì)有內(nèi)碎片,不過每個(gè)內(nèi)碎片不會(huì)超過頁(yè)的大小,這個(gè)開銷相比之前的方法來說是可以接受的。一個(gè)程序不必連續(xù)存放,但也要求程序全部裝入內(nèi)存才能執(zhí)行。
5 分頁(yè)硬件支持
回顧分頁(yè)的過程,如下圖,在頁(yè)數(shù)比較小的時(shí)候可以直接把頁(yè)表放入寄存器,但當(dāng)頁(yè)數(shù)很多的時(shí)候,顯然是要將頁(yè)表放入內(nèi)存中:
將頁(yè)表放入內(nèi)存后,要知道放在了內(nèi)存的哪個(gè)地方,這里引入了兩個(gè)寄存器來保存頁(yè)表的位置:
- 頁(yè)表基址寄存器 Page-table base register (PTBR):頁(yè)表基址寄存器指向頁(yè)表的起始地址;
- 頁(yè)表限長(zhǎng)寄存器 Page-table length register (PRLR):頁(yè)表限長(zhǎng)寄存器表明頁(yè)表的長(zhǎng)度。
在這個(gè)機(jī)制中,每一次的數(shù)據(jù)/指令存取需要兩次內(nèi)存存取,一次是存取頁(yè)表,一次是存取數(shù)據(jù),兩次的存取顯然性能不高,解決辦法是通過一個(gè)聯(lián)想寄存器 translation look-aside buffers (TLBs),可以解決兩次存取的問題。
聯(lián)想寄存器類似于一個(gè)快速緩存,每次查找一個(gè)頁(yè)的時(shí)候,都記錄下頁(yè)和頁(yè)的起始地址,當(dāng)下次查詢的時(shí)候可以直接在聯(lián)想寄存器中尋找,找不到的時(shí)候再去查找頁(yè)表,此時(shí)地址映射的過程如下,相比在第四節(jié)中最后的那張圖多了一個(gè)聯(lián)想寄存器的查找步驟:
我們知道寄存器的存取速度是比內(nèi)存快的,因此用這種方法能大大提高查找效率,舉個(gè)例子,我們假設(shè)聯(lián)想寄存器的查找需要時(shí)間 εεε,內(nèi)存一次存取要111微秒,我們稱如果在聯(lián)想寄存器中找到了對(duì)應(yīng)的頁(yè)地址的話,叫做“命中”,那么命中率 ααα 就為在聯(lián)想寄存器中找到頁(yè)號(hào)的比率,比率與聯(lián)想寄存器的大小有關(guān),此時(shí)有效的存取時(shí)間 T=(1+ε)α+(2+ε)(1–α)=2+ε–αT=(1 + ε) α + (2 + ε)(1 – α)=2 + ε – αT=(1+ε)α+(2+ε)(1–α)=2+ε–α。
可以帶入具體數(shù)值來看一看,例如,假設(shè)檢索聯(lián)想存儲(chǔ)器的時(shí)間為 20ns20ns20ns ,訪問內(nèi)存的時(shí)間為 100ns100ns100ns ,訪問聯(lián)想存儲(chǔ)器的命中率為 85% ,則 CPU 存取一個(gè)數(shù)據(jù)的平均時(shí)間為 T=0.85?120+0.15?220=135nsT=0.85*120+0.15*220=135nsT=0.85?120+0.15?220=135ns,訪問時(shí)間只增加 35%。如果不引入聯(lián)想存儲(chǔ)器,其訪問將延長(zhǎng)一倍(達(dá) 200ns200ns200ns )
下圖是分頁(yè)地址變換機(jī)構(gòu)工作原理圖,首先按頁(yè)的大小分離出頁(yè)號(hào)和位移量,放入有效地址寄存器中,再將頁(yè)號(hào)與頁(yè)表長(zhǎng)度進(jìn)行比較,如果頁(yè)號(hào)大于頁(yè)表長(zhǎng)度,越界中斷;再以頁(yè)號(hào)為索引查找頁(yè)表:將頁(yè)表始址與頁(yè)號(hào)和頁(yè)表項(xiàng)長(zhǎng)度的乘積相加,便得到該表項(xiàng)在頁(yè)表中的位置,于是可從中得到該頁(yè)的物理塊號(hào);然后將該物理塊號(hào)裝入物理地址寄存器的高址部分;最后將有效地址寄存器中的位移量直接復(fù)制到物理地址寄存器的低位部分,從而形成內(nèi)存地址:
下面是一個(gè)具體的例子,圖中省略了越界判斷,先分離出了頁(yè)號(hào)和偏移,分別為 2 和 1C4,然后查找頁(yè)表,得到塊號(hào)地址為 8,然后將 8 放在物理地址寄存器的高位,把偏移 1C4 放在物理地址寄存器的低位,這個(gè)地址就是物理地址:
6 分段管理
上面所討論的分頁(yè)方式有效的解決了外碎片問題,但是實(shí)際上并沒有考慮用戶的觀點(diǎn),也就是它在分頁(yè)的時(shí)候都是硬性的按照等大小來劃分,并不關(guān)心頁(yè)中存放的是程序還是數(shù)據(jù)。本節(jié)中引入的分段方式就是一種支持用戶觀點(diǎn)的內(nèi)存管理機(jī)制。
一個(gè)程序是一些段的集合,一個(gè)段是一個(gè)邏輯單位,如主程序、子過程、函數(shù)、局部變量、全局變量等等內(nèi)容,在用戶的眼里是把程序看作各個(gè)有機(jī)的部分,如下圖:
把程序的各個(gè)部分放入內(nèi)存實(shí)際上也就是把這每個(gè)部分看成各個(gè)段,然后放入內(nèi)存,如下圖:
在分段管理方式下要解決的問題依舊是邏輯地址到物理地址的映射問題,與分頁(yè)類似,分段管理方式下也有段表,和段偏移。由于分頁(yè)的每一頁(yè)都是固定大小的,所以只需要起始地址,但是分段的每一段大小是不等長(zhǎng)的,所以這里定義了兩個(gè)變量:
- 基址 (base):包括內(nèi)存中段物理地址的起始地址;
- 限長(zhǎng) (limit):指定段的長(zhǎng)度;
從邏輯地址到物理地址的映射過程如下圖所示,段表中保存著每一段的起始地址和線長(zhǎng)地址,這樣就在內(nèi)存中唯一確定了段的地址范圍:
下圖是實(shí)現(xiàn)地址映射的物理結(jié)構(gòu)流程圖,其過程和分頁(yè)的過程十分類似:
在分頁(yè)方式中,頁(yè)表是要保存在內(nèi)存中的,所以當(dāng)時(shí)定義了頁(yè)表基址寄存器(PTBR)和頁(yè)表限長(zhǎng)寄存器 (PRLR)來指明頁(yè)表的位置,同樣在分段方式中,也定義了類似的兩個(gè)寄存器:
- 段表基址寄存器 Segment-table base register (STBR):段表基址寄存器指向段表在內(nèi)存中的地址;
- 段表限長(zhǎng)寄存器 Segment-table length register (STLR):段表限長(zhǎng)寄存器表明被一個(gè)程序所使用的段的數(shù)目。
此時(shí)地址變化過程如下圖,首先系統(tǒng)將邏輯地址中的段號(hào) S 與段表長(zhǎng)度 TL 進(jìn)行比較。若 S≥TL,訪問越界,若未越界,則根據(jù)段表的始址和該段的段號(hào),計(jì)算出該段對(duì)應(yīng)段表項(xiàng)的位置,從中讀出該段在內(nèi)存中的起始地址;然后再檢查段內(nèi)地址 d 是否超過該段的段長(zhǎng) SL 。若超過,即 d≥SL,同樣發(fā)出越界中斷信號(hào);若未越界,則將該段的基址與段內(nèi)地址 d 相加,得到要訪問的內(nèi)存物理地址。
總結(jié)
以上是生活随笔為你收集整理的操作系统原理第八章:内存管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统原理第七章:死锁
- 下一篇: 操作系统原理第九章:虚拟内存