『壹』 誰有操作系統復習題啊
操作系統作業
第一章 序言
1. 選擇題
1.1 ( )不是一個操作系統環境。 A.賽揚(celeron) B.Windows CE C.Linux D.Solaris。
1.2 批處理操作系統的缺點是( ) A.系統吞吐量小 B.CPU利用率低 C.系統開銷小 D.缺少交互能力
1.3 批處理操作系統的目的是( )
A.提高系統與用戶的交互性 B.提高系統資源利用率 C.提高系統吞吐率 D.降低用戶作業的周轉時間
1.4 實時操作系統必須在( )時間內響應一個新任務。A.一個機器周期 B.被控對象規定 C.任意周期 D.時間片
1.5 下列系統中,( )是實時系統。 A.火炮的自動化控制系統B.辦公自動化系統C.管理信息系統D.計算機集成製造系統
1.6 如果分時操作系統的時間片一定,那麼( ) ,則響應時間越長。A. 用戶數越少B. 用戶數越多C. 內存越少 D. 內存越多
1.7 分時系統通常採用( )策略為用戶服務。 A. 可靠性和靈活性 B. 時間片輪轉 C. 時間片加權分配 D. 短作業優先
1.8 多道批處理系統中引入了多道程序設計技術。為了充分提高各種資源的利用率,作業的類型最好是( )
A. 短作業型 B. 計算型,即其CPU計算的工作量重於I/O的工作量
C. I/O型,即其I/O的工作量重於CPU計算的工作量 D. 計算與I/O均衡型
2.填空題
2.1 在分時系統中,影響響應時間的主要因素有___ __、__ _。
2.2 設計實時系統時應特別強調系統的_ _和_ _。
2.3 操作系統的特徵主要有:__ ___、_ _、_ _及 。
2.4 多道程序設計的特點是多道、 和 。
2.5 現代操作系統的兩個最基本的特性是程序的 與系統資源的 。
3. 判斷題
3.1 操作系統的主要作用是管理系統資源和提供用戶界面。( )
4.簡答題
4.1 並發與並行有何區別?
4.2 多道程序設計的主要優點是什麼?
4.3 多用戶分時系統如何保證系統的交互性?
第二章 操作系統結構
1. 選擇題
1.1 用戶使用操作系統通常有四種介面:終端命令、圖形界面、系統調用和( )。
A.高級指令 B. 宏命令 C. 匯編語言 D. 作業控制語言
1.2 操作系統在執行系統調用時會產生一種中斷,這種中斷稱為( )。A.系統中斷 B. I/O中斷 C. 程序性中斷 D. 軟中斷
1.3 在下列操作中,不必將控制進入操作系統的操作是( )。A.中斷 B. 鍵盤命令 C. 系統調用 D. 程序調用
1.4 ( )中斷是正在運行的進程所期待的自願中斷事件。A.程序 B. I/O C. 時鍾 D. 訪管
1.5 當用戶程序執行訪管指令時,系統( )。A. 維持在目態 B. 維持在管態 C. 從管態到目態 D. 從目態到管態
2.填空題
2.1 根據中斷信號的來源,可分把中斷為 和 二大類,屬於第一類的中斷有 ,屬於第二類的中斷有 。
2.2 根據中斷信號的含義和功能,可把中斷分為以下五類:機器故障中斷、I/O中斷、外中斷、 和 。
2.3 用戶程序是通過使用_ __產生中斷進入系統內核的。 2.4 系統調用與一般過程的主要區別是_ _。
2.5 特權指令可以在中央處理器處於 時予以執行。
3. 判斷題
3.3 特權指令僅允許在管態下執行。( ) 3.4 斷點與恢復點是一致的。( )
3.5 就執行效率而言,解釋程序要比編譯程序好一些。( ) 3.6 解釋程序是用來逐句分析執行源程序的系統軟體。( )
3.8 命令處理程序執行完上一條命令後才接著處理下一條命令。( ) 3.9 中斷向量是指中斷處理程序入口地址。( )
3.10 用戶程序有時也可以在核心態下運行. ( )
4.簡答題
4.1 什麼是中斷與中斷系統? 4.2 什麼是管態與目態?
4.3 什麼是(外)中斷?什麼是異常? 4.4系統調用與一般用戶函數調用的區別?
5.問答題
5.1 根據中斷信號的含義與功能,中斷可以分為哪幾類?
第三章 進程與處理機管理
1. 選擇題
1.1 從作業提交到作業完成的時間間隔是( )。A. 響應時間 B. 周轉時間 C. 運行時間 D. 等待時間
1.2 既考慮作業等待時間,又考慮作業執行時間的調度演算法是( )。
A. 優先數調度 B. 先來先服務 C. 短作業優先 D. 最高響應比優先
1.3 一個進程被喚醒意味著( )。A. 進程重新佔有CPU B. 進程變為執行狀態C. PCB移到等待隊列首 D. 進程變為就緒狀態
1.4 在下列事件中不立即進入進程調度程序進行調度的是( )。A. 等待I/O B. 時間片到 C. 進程執行完 D. 輸入新作業
1.5 UNIX系統的進程調度策略是基於( )。A. 時間片調度 B. 先來先調度 C. 短進程優先調度 D. 動態優先調度
1.6 如下所述的工作中,( )不是創建進程所必須做的。
A. 為進程分配CPU B. 為進程分配內存C. 建立一個PCB D. 將PCB鏈入就緒隊列
1.7 進程管理中,在( )情況下,進程的狀態由等待變為就緒。
A. 進程被調度 B. 等待某一事件 C. 時間片用完 D. 等待的事件發生
1.8 當作業調度程序將某作業調入內存並建立一個相應進程時,該進程的狀態處於( )。
A. 等待狀態 B. 後備狀態 C. 就緒狀態 D. 執行狀態
1.9 系統處理某一緊急任務時,應選擇( )。A. 最高響應比優先 B. 優先數調度 C. 短作業優先 D. 先來先服務
1.10 在下列狀態中不是屬於進程狀態的是( )。A. 等待狀態 B. 後備狀態 C. 就緒狀態 D. 執行狀態
1.11 在單處理機上執行多道程序,是在( )進行的。A. 同一時刻 B. 某一時刻 C. 同一時間間隔內 D. 某一時間間隔內
1.12 如下的進程狀態變化,不可能發生的是( )。A. 運行->就緒 B. 運行->等待 C. 等待->就緒 D. 等待->運行
1.13 當作業處於( )狀態時,已處於進程管理之下。A. 等待 B. 後備 C. 執行 D. 完成
1.14 當某進程被調度建立一個相應的進程並分配到必要的資源,該進程的狀態是( )。
A. 等待狀態 B. 後備狀態 C. 就緒狀態 D. 執行狀態
2.填空題
2.1 一個用作業說明書組織的批處理作業,其作業體一般由_ _ 、_ _和_ _組成。
2.2 按作業到達時間的先後進行調度稱為__ 調度演算法,按作業執行時間的長短進行調度稱為__ __調度演算法,既考慮到等待時間又考慮到執行時間的調度演算法稱為__ __調度演算法。
2.3 操作系統內核的主要功能是__ __。
2.4 系統中用以表徵進程的數據結構是_ _,表徵「作業」的數據結構是_ 。
2.5 進程的基本狀態有 。 2.6 進程的基本屬性有__ __。
2.7 並行性是指兩個或多個事件在_ __發生;並發性是指兩個或多個事件在 _ 發生。
2.8 處於執行狀態的進程被高優先順序進程剝奪時,其狀態變為__ __。
2.9 進程映象由_ __、_ __和_ __組成。
2.10 當系統建立一個進程時,系統就為其建立一個_ __,當進程被撤銷時就將其收回。
2.11 在時間片調度演算法中,如果時間片過大,則該調度演算法就會退化為__ _。
3. 判斷題
3.1 程序的並發與系統資源的共享是現代操作系統的兩個基本特性。( )
3.2 當後備狀態的作業被高級調度程序選中進入內存後,其相應的進程處於執行狀態。( )
3.3 一個作業的處理由一個相應的進程來完成。( )
3.4 進程的就緒隊列也是一個在一個時刻只允許一個進程訪問的臨界資源。( )
3.5 進程與程序是一 一對應的。( )
3.6 進程由執行狀態變為等待狀態是因為等待I/O操作完成、等待其他進程發來消息,等待
獲取某個資源的使用等。( ) 3.7 進程由程序、數據和進程式控制制塊組成。( )
3.8 實時系統中進程調度應採用非剝奪式調度方式。( ) 3.9 一個進程只能執行一個程序代碼。( )
3.10 操作系統中,第一個進程是在系統初啟時由初始化程序生成的。( )
3.11 作業調度程序也可以作為一個進程運行。( ) 3.12 進程式控制制塊中的所有信息必須常駐內存. ( )
4.問答題
4.1 進程式控制制塊PCB的作用是什麼?它主要包含哪些內容? 4.2 簡述創建進程的大致過程。
4.3 進程和線程的主要區別是什麼? 4.4 試從動態性、並發性、獨立性三個方面比較程序與進程。
4.5 試說明進程在三個基本狀態之間轉換的典型原因。 4.6 掛起狀態具有那些性質?
4.7 引起進程阻塞或被喚醒的主要事件是什麼?
5. 計算題
5.1 假設在單處理機上中有五個進程P1,P2,P3,P4,P5幾乎同時創建,其運行時間(單位:ms)分別為10,1,2,1,5,其優先數分別為3,5,1,2,4(1為最低優先順序)。系統時間片為1ms。試計算分別採用下列調度演算法時進程的平均周轉時間。(1)HPF(高優先順序調度演算法) (2)RR(時間片輪轉調度演算法),輪轉順序為P1,P2,P3,P4,P5。
5.2設單道批處理系統中有作業J1,J2,J3,J4,其提交時間分別為8.5,8.0,9.0,9.1;其運行時間分別為0.5, 1.0,0.2,0.1。試計算分別採用FCFS、SJF和HRF調度演算法時的平均周轉時間。
第四章 進程同步與通信、進程死鎖
1. 選擇題
1.1 在同步控制中,所謂的臨界區是指( )。A.一個緩沖區 B. 一段共享數據區 C. 一段程序 D. 一個互斥的硬體資源
1.2 對於兩個並發進程,設互斥信號量為mutex,若mutex=0,則表示( )。
A. 沒有進程進入臨界區 B. 一個進程進入臨界區 C. 一個進入另一個等待 D. 二個進程進入臨界區
1.3 在生產者-消費者問題中,設置信號量empty以確保生產者進程能向緩沖區存入信息,設置信號量full以確保消費者進程能從緩沖區中取出信息,當生產者進程向緩沖區存入信息後應執行以下的那一種PV操作( B )。
A. P(empty) B. V(full) C. P(full) D. V(empty)
1.4 若信號量s的初值為3,且有4個進程共享某臨界資源,則s的取值范圍是( )。A. [-3,3] B. [-1,3] C. [0,3] D. [-4,3]
1.5 為了防止死鎖某系統採用一次性分配全部資源的方法,這種方法是破壞了產生死鎖的那一個必要條件( )。
A. 互斥資源 B. 佔有等待 C. 循環等待 D. 非剝奪式分配
1.6 在解決死鎖的方法中屬於死鎖防止的策略是( )。A. 死鎖檢測法 B. 資源分配圖化簡C. 銀行家演算法 D. 資源有序分配法
1.7 Dijkstra提出的銀行家演算法是具有代表性的( )演算法。A. 預防死鎖 B. 避免死鎖 C. 檢測死鎖 D. 解除死鎖
1.8 系統中有3個並發進程都需要同類資源4個,則系統不會發生死鎖的最少資源數是( )A. 8 B. 9 C. 10 D. 11
1.9 某系統中有同類互斥資源m個,可並發執行且共享該類資源的進程有n個,每個進程申請該類資源的最大量為x(n≤x≤m),當不等式( )成立時,系統一定不發生死鎖。A. nx+1≤m B. nx≤m C. m(x-1)+1≤n D. m-nx+(n-1)≥0
2.填空題
2.1 一次僅允許一個進程使用的資源叫 ,訪問這種資源的那段程序稱為 。
2.2 信號量的物理意義是:信號量大於零表示_ _,信號量小於零其絕對值表示__ _。
2.3 有n個進程共享同一臨界資源,若使用信號量機制實現對臨界資源的互斥訪問,則信號量的變化范圍是_ _。
2.4 如果信號量的當前值為-4,則表示系統中在該信號量上有 個等待進程。
2.5 進程間的制約關系可分為兩類:_ __和_ _,其中_ _指合作進程之間具有一定的邏輯關系;_ __指進程間在使用共享資源方面的約束關系。
2.6 原語在執行過程中必須___ _。
2.7 從資源分配的角度看,P操作意味著向系統_ _資源,V操作意味著向系統__ _資源。
2.8 死鎖的必要條件是:__ __、__ _、_ __、_ __。 2.9 死鎖的充要條件是: 。
2.10 一次性分配進程所需的全部資源,這種預防死鎖的方法破壞了產生死鎖四個必要條件中的__ __條件。
2.11 採用 資源循序分配法,可以破壞產生死鎖四個必要條件中的__ __條件。
2.12 產生死鎖的主要原因是___ __、___ __和資源分配不當。
3. 判斷題
3.1 進程的同步與互斥是進程的二種狀態。( ) 3.2 所有進程都掛起時, 系統陷入死鎖. ( )
3.3 如果信號量S的當前值為-5, 則表示系統中共有5個等待進程. ( )
3.4 系統出現死鎖與資源的分配策略有關,與進程執行的相對速度無關。( )
3.5 一旦出現死鎖, 所有進程都不能運行。( ) 3.6 參與死鎖的進程至少有兩個已經佔有資源. ( )
3.7 有m個進程的操作系統出現死鎖時, 死鎖進程的個數為1<k≤m. ( ) 3.8 系統處於不安全狀態不一定是死鎖狀態. ( )
4.簡答題
4.1無忙等待的P、V操作是怎樣定義的?
4.2多個進程對信號量S進行了5次 P操作,2次V操作後,現在信號量的值是 -3,與信號量S相關的處於阻塞狀態的進程有幾個?信號量的初值是多少?
5.綜合題
5.1 假設三個並發進程P,Q,R。P和Q共享緩沖區A(有m個單元),Q和R共享緩沖區B(有n個單元),進程P負責從輸入設備上讀入信息並寫入緩沖區A,進程Q從緩沖區A讀出信息,加工後寫入緩沖區B,進程R負責從緩沖區B讀出信息並列印,寫出模擬P,Q,R三進程的並發程序。
5.2 設某系統中有4個並發進程P1、P2、P3、P4合作完成某一任務,P1執行完後才能執行P2和P3,P2和P3執行完後才能執行P4,試畫出優先圖描述這4個進程間的關系,然後用PV操作實現。
5.3 某高校招生大廳只能容納150人,當少於150人時,學生可以進入大廳辦理入學手續;否則,需在外等候。若將每一個學生作為一個進程,請用P、V操作編程。
5.4兩雙胞胎兄弟共同使用一個銀行帳號,約定每次限存或限取100元。設存錢與取錢兩個進程是並發的,存錢進程與取錢進程的程序如下所示。假如最初帳戶上有200元,哥哥第一次存錢時,弟弟取錢。請問最後帳號money可能出現的值是多少?如何用PV操作實現兩並發進程的正確執行?
int money=200;
// Parbegin和Parend之間的程序並發執行
Parbegin
void Save( ) //存錢
{ int m1;
m1=money;
m1=m1+100;
money=m1;
}
void Take( ) //取錢
{ int m2;
m2=money;
if(m2>=100){
m2=m2-100;
money=m2;
}
}
Parend;
5.5 化簡下列資源分配圖,說明有無進程處於死鎖狀態?
5.6 一個計算機系統中擁有8個USB口,現有P個進程競爭使用,每個進程要求兩台,試問,P的值如何選取時系統中絕對不會出現死鎖?
5.7 某系統有165個存儲單元。設四個進程p1、p2、p3、p4對存儲單元的最大需求數分別為70、35、25、100,在T0時刻,四個進程已分配的存儲單元數分別為25、15、15、25。試用銀行家演算法說明系統在T0時刻是否存在安全序列。
第五章 存儲管理
1. 選擇題
1.1 MS-Dos操作系統的命令處理程序分為常駐、暫駐二部分,其暫駐部分存放在主存中的高地址區域,以便用戶區可向該區域擴展,這種存儲管理技術稱為( )。A. 虛存管理 B. 交換 C. 覆蓋 D. 重定位
1.2 在虛擬存儲管理中,為了避免不必要的信息寫入,在頁表中須設置( )。A. 主存塊號 B. 輔存地址 C. 訪問位 D. 修改位
1.3 在頁面淘汰演算法中,淘汰駐留集中下次訪問離當前訪問的頁面最遠的頁面,這種頁面淘汰演算法稱為( )。
A. OPT演算法 B. FIFO演算法 C. LRU演算法 D. WS演算法
1.4 一個目標程序所限定的存儲范圍稱為該程序的( D )。A. 名空間 B. 地址空間 C. 物理空間 D. 符號空間
1.5 分段管理中,( )。
A.段與段之間必定連續 B. 以段為單位分配,段內連續 C. 段與段之間必定不連續 D. 以段為單位分配,每段等長
1.6 在下列存儲管理方式中,不要求連續空間且不要求作業全部裝入的管理方式是( )。
A. 單道連續 B. 請求式分頁管理 C. 分頁管理 D. 可變式分區管理
1.7 能夠實際增加存儲單元的存儲擴充方式是( )。A. 覆蓋技術 B. 交換技術 C. 物理擴充 D. 虛存技術
1.8 LRU頁面淘汰演算法選擇( )頁面作為淘汰頁面。A. 最先進入 B 訪問次數最少 C. 此前最長時間未訪問 D 此後最長時間未訪問
1.9 在存儲管理中,所謂的虛擬存儲技術是指( )的技術。A. 擴充邏輯空間B. 擴充內存空間C. 擴充外存空間D. 擴充存儲空間
1.10 採用( ),目標程序可以不經任何改動而裝入內存。A. 靜態重定位 B. 動態重定位 C.交換技術 D. 覆蓋技術
1.11 在下列概念中,與虛存有關的概念是( )。A. 最佳適應 B. 覆蓋技術 C. 動態可變 D. 抖動
1.12 要求存儲分配時地址連續的管理方式是( )。A. 分區管理 B. 段式管理 C. 分頁管理 D. 段頁式管理
1.13 將暫不執行的進程映象移到外存,讓出內存空間另作它用的技術是( )。A. 覆蓋技術B. 交換技術C. 物理擴充 D. 虛存技術
1.14 在下列存儲管理方法中,屬於連續分區管理方法的是( )。A. 頁式 B. 段式 C. 虛擬方法 D. 可變分區
1.15 為了使大作業可在小的主存空間中運行,可採用的技術是 A. 頁式管理B. 段式管理C. 請求式分頁管理 D. 可變式分區管理
1.16 程序的( )原理是虛擬存儲管理系統的基礎。A. 動態性 B. 虛擬性 C. 局部性 D. 全局性
2.填空題
2.1 可變分區法管理中, 法採用按起始地址的遞增順序排列空區。 __ _法採用按空塊長度的遞增順序排列空區。
2.2 為了提高內存的使用效率,將暫不執行的進程映象移到外存,當具備執行條件時再將它調入內存,這種存儲管理技術稱為 。
2.3 在程序開始裝入時先裝入部分模塊,當程序運行過程中調用另一模塊時再從外存調入到同一內存區域,這種存儲管理技術稱為_ __。
2.4 在頁式管理系統中,用戶程序中使用的地址稱為__ __,由系統將它轉化為___ _。
2.5. 用戶編程時使用 地址,處理機執行程序時使用 地址。
2.6 分頁管理是把內存分為大小相等的區,每個區稱為__ _,而把程序的邏輯空間分為若干__ _,頁的大小與頁幀的大小相等。
2.7 在分頁存儲管理中,為了加快地址變換速度,頁面大小的值應取_ __。
2.8 在請求式分頁系統中,被調出的頁面又立刻被調入,這種頻繁的調頁現象稱為_ _。
2.9 採用可變式分區法管理主存,存儲空間存在_ ,可用 方法消除。
2.10 分段管理中,若邏輯地址中的段內地址大於段表中該段的段長,則發生_ 。
2.11 段頁式存儲管理中,每道程序都有一個 表和若干個 表。
2.12 頁式管理系統的地址結構由__ __和_ __組成。
2.13 分段管理中的地址映射過程是:首先找到該作業段表的__ ___,然後根據邏輯地址中的_ 去查找段表得到該段的內存開始地址,再與邏輯地址中的__ __相加得到物理地址。
2.14 存儲管理的任務是_ _、_ __、_ _和_ __。
2.15 _ _也稱為__ _不是把一個進程映象的所有頁面一次性全部裝入內存,而只裝入一部分,其餘部分在執行中動態調入。
2.16 在段頁式管理中,邏輯地址由__ __、_ _、__ 三部分組成。
3. 判斷題
3.1 可共享的程序代碼被稱為可重入代碼或純代碼,運行過程中不能被改變。( )
3.2 高速小容量聯想存儲器用於減少地址變換中訪問主存的次數。( )
3.3 在可變式分區存儲管理中,要求用戶的一道作業必須放在一片連續的存儲空間中。( )
3.4 缺頁時,淘汰駐留內存時間最長的頁面是比較合理的。( )
3.5 動態重定位可使目標程序不經任何改動就可裝入內存,且可任意浮動。( )
3.6 虛擬存儲器空間實際上就是輔存空間。( ) 3.7 請求式分頁系統中,不要求進程映象一次全部裝入內存。( )
3.8 簡單分頁管理控制簡單,但易產生系統抖動。( ) 3.9 在分區存儲管理中,一道作業必須存放在連續區域中。( )
3.10 請求式分頁系統用時間換取空間,這是請求式分頁管理方式的缺點。( )
3.11 頁面替換演算法都滿足:『存儲塊數越多,缺頁中斷就越少』的規律。( )
3.12 段式管理中,若邏輯地址中的段內地址小於段表中該段的段長,則發生越界中斷。( )
3.13 頁式存儲管理方式比段式存儲管理方式更易於實現保護和共享。( )
3.14 段式管理以段為單位分配內存,段內連續,但段間不一定連續。( )
3.15 虛存空間定義越大,則相應的效率就越高。( ) 3.16 虛擬存儲系統可以在每一台計算機上實現. ( )
4.簡答題
4.1 交換技術與虛存中使用的調入調出技術有何相同和不同之處? 4.2 什麼是抖動現象?
4.3 段頁式存儲系統中,若不考慮聯想存儲器,為了獲得一條指令或數據,需訪問幾次內存?
4.4何謂虛擬存儲器,並舉一例說明操作系統如何實現虛擬內存的?
5.綜合題
5.1 某虛擬存儲器,用戶編程空間32個頁面,每頁1KB,主存為8KB,假定某時刻用戶的第2,3,5,7頁分配的物理塊號分別為6,7,4,2,問:虛地址0F80(十六進制)所對應的物理地址為多少?邏輯地址的有效位是多少?物理地址需要多少位?
5.2 在某個採用頁式存儲管理的系統中,現有J1、J2和J3共3個作業同駐主存。其中J2有4個頁面,被分別裝入到主存的第3、4、6、8頁幀中。假定頁面大小為1024位元組,
主存容量為10kB位元組。(1) 設每個頁表項只由頁號和頁幀號組成,試寫出J2的頁表。 (2) 當J2在CPU上運行時,執行到其地址空間第500號處遇到一條傳送指令: MOV 2100, 3100
請計算MOV指令中兩個操作數(十進制數)的物理地址?
5.3 某採用頁式虛擬存儲管理的系統,接收了一個共7頁的作業,作業執行時依次訪問的頁號為1、2、3、4、2、1、5、6、2、1、2、3、7、4、3、2、6。設駐留集大小為4,若分別採用FIFO和LRU頁面替換策略,求作業訪問上述頁號產生多少次頁故障?寫出依次產生頁故障後應淘汰的頁。
5.4 在一虛存系統中,採用LRU淘汰演算法,每個進程可有3個頁幀內存空間,每頁可存放200個整數。其中第一頁存放程序,且假定程序已經在內存。下列程序A和程序B用二維整型數組A[100,100]存儲數據,分別就程序A和程序B的執行過程計算缺頁數。
程序A: for(int i=1; i<=100; i++) for(int j=1; j<=100;j++) A[i,j]=0;
程序B: for(int j=1; j<=100; j++) for(int i=1; i<=100;i++) A[i,j]=0;
5.5 現有一個分頁式管理系統,其頁表設置在內存中,若對內存的一次存取需要1.5us,則訪問一次邏輯地址的存取的等效訪問時間時間是多少?現有一聯想存儲器,其平均命中率為80%,當頁表項在聯想存儲器中時其查找時間忽視不計,試問採用聯想存儲器時的存取的等效訪問時間為多少?若命中率為90%,則等效訪問時間又為多少?
『貳』 避免死鎖的方法有哪些
1、避免給一個鎖嵌套上鎖,在持有一個鎖的時候,不要再給這個鎖上鎖。如果使用多個鎖,使用std::lock。
2、在持有鎖時,不要調用別人提供的函數,因為你不清楚別人的代碼怎麼實現的,不知道它是不是在使用鎖。
3、給多個鎖上鎖時,固定順序。如果在給多個所上鎖,並且無法使用std::lock,最好的做法就是在每一個線程中,都按照同樣的順序。
4、分層次來使用鎖,把程序分成幾個層次。區分每個層次中使用的鎖,當一個線程已經持有更低層次的鎖時,不允許使用高層次的鎖。可以在程序運行時給不同的鎖加上層次號,記錄每個線程持有的鎖。
(2)銀行家演算法允許的最大並發性擴展閱讀:
解決方法
在系統中已經出現死鎖後,應該及時檢測到死鎖的發生,並採取適當的措施來解除死鎖。
死鎖預防。
這是一種較簡單和直觀的事先預防的方法。方法是通過設置某些限制條件,去破壞產生死鎖的四個必要條件中的一個或者幾個,來預防發生死鎖。預防死鎖是一種較易實現的方法,已被廣泛使用。但是由於所施加的限制條件往往太嚴格,可能會導致系統資源利用率和系統吞吐量降低。
死鎖避免。
系統對進程發出的每一個系統能夠滿足的資源申請進行動態檢查,並根據檢查結果決定是否分配資源;如果分配後系統可能發生死鎖,則不予分配,否則予以分配。這是一種保證系統不進入死鎖狀態的動態策略。
死鎖檢測和解除。
先檢測:這種方法並不須事先採取任何限制性措施,也不必檢查系統是否已經進入不安全區,此方法允許系統在運行過程中發生死鎖。但可通過系統所設置的檢測機構,及時地檢測出死鎖的發生,並精確地確定與死鎖有關的進程和資源。檢測方法包括定時檢測、效率低時檢測、進程等待時檢測等。
然後解除死鎖:採取適當措施,從系統中將已發生的死鎖清除掉。
這是與檢測死鎖相配套的一種措施。當檢測到系統中已發生死鎖時,須將進程從死鎖狀態中解脫出來。常用的實施方法是撤銷或掛起一些進程,以便回收一些資源,再將這些資源分配給已處於阻塞狀態的進程,使之轉為就緒狀態,以繼續運行。死鎖的檢測和解除措施,有可能使系統獲得較好的資源利用率和吞吐量,但在實現上難度也最大。
『叄』 操作系統題目,好的追加高分,感謝大蝦
http://tieba..com/f?kz=588380474
http://blog.163.com/mqt_signature/blog/static/1049595722009429104343122/
或者看看這個,可是你需要的
《操作系統--銀行家演算法》
課程設計報告
1 課程設計目的 …………………………………………………… 1
2 課程設計的要求 ………………………………………………… 1
3 課程設計題目描述 ……………………………………………… 2
4 課程設計之銀行家演算法原理 …………………………………… 2
5 源程序結構分析及代碼實現 …………………………………… 4
6 課程設計總結 …………………………………………………… 25
一、課程設計的目的
操作系統是計算機系統的核心系統軟體,它負責控制和管理整個系統的資源並組織用戶協調使用這些資源,使計算機高效的工作。《操作系統課程設計》是《操作系統》理論課的必要補充,是復習和檢驗所學課程的重要手段,本課程設計的目的是綜合應用學生所學知識,通過實驗環節,加深學生對操作系統基本原理和工作過程的理解,提高學生獨立分析問題、解決問題的能力,增強學生的動手能力。
二、課程設計的要求
1.分析設計內容,給出解決方案(要說明設計實現的原理,採用的數據結構)。
2.畫出程序的基本結構框圖和流程圖。
3.對程序的每一部分要有詳細的設計分析說明。
4.源代碼格式要規范。
5.設計合適的測試用例,對得到的運行結果要有分析。
6.設計中遇到的問題,設計的心得體會。
7.按期提交完整的程序代碼、可執行程序和課程設計報告。
三、課程設計題目描述
銀行家演算法是一種最有代表性的避免死鎖的演算法。
要解釋銀行家演算法,必須先解釋操作系統安全狀態和不安全狀態。
安全狀態:如果存在一個由系統中所有進程構成的安全序列P1,…,Pn,則系統處於安全狀態。安全狀態一定是沒有死鎖發生。
不安全狀態:不存在一個安全序列。不安全狀態不一定導致死鎖。
那麼什麼是安全序列呢?
安全序列:一個進程序列{P1,…,Pn}是安全的,如果對於每一個進程Pi(1≤i≤n),它以後尚需要的資源量不超過系統當前剩餘資源量與所有進程Pj (j < i )當前佔有資源量之和。
銀行家演算法:
我們可以把操作系統看作是銀行家,操作系統管理的資源相當於銀行家管理的資金,進程向操作系統請求分配資源相當於用戶向銀行家貸款。操作系統按照銀行家制定的規則為進程分配資源,當進程首次申請資源時,要測試該進程對資源的最大需求量,如果系統現存的資源可以滿足它的最大需求量則按當前的申請量分配資源,否則就推遲分配。當進程在執行中繼續申請資源時,先測試該進程已佔用的資源數與本次申請的資源數之和是否超過了該進程對資源的最大需求量。若超過則拒絕分配資源,若沒有超過則再測試系統現存的資源能否滿足該進程尚需的最大資源量,若能滿足則按當前的申請量分配資源,否則也要推遲分配。
四、課程設計之銀行家演算法原理
1.銀行家演算法的思路
先對用戶提出的請求進行合法性檢查,即檢查請求的是不大於需要的,是否不大於可利用的。若請求合法,則進行試分配。最後對試分配後的狀態調用安全性檢查演算法進行安全性檢查。若安全,則分配,否則,不分配,恢復原來狀態,拒絕申請。
2.銀行家演算法中用到的主要數據結構
可利用資源向量 int Available[j] j為資源的種類。
最大需求矩陣 int Max[i][j] i為進程的數量。
分配矩陣 int Allocation[i][j]
需求矩陣 int need[i][j]= Max[i][j]- Allocation[i][j]
申請各類資源數量 int Request i[j] i進程申請j資源的數量
工作向量 int Work[x] int Finish[y]
3.銀行家演算法bank()
進程i發出請求申請k個j資源,Request i[j]=k
(1)檢查申請量是否不大於需求量:Request i[j]<=need[i,j],若條件不符重新輸入,不允許申請大於需求量。
(2)檢查申請量是否小於系統中的可利用資源數量:Request i[j]<=available[i,j],若條件不符就申請失敗,阻塞該進程,用goto語句跳轉到重新申請資源。
(3)若以上兩個條件都滿足,則系統試探著將資源分配給申請的進程,並修改下面數據結構中的數值:
Available[i,j]= Available[i,j]- Request i[j];
Allocation[i][j]= Allocation[i][j]+ Request i[j];
need[i][j]= need[i][j]- Request i[j];
(4)試分配後,執行安全性檢查,調用safe()函數檢查此次資源分配後系統是否處於安全狀態。若安全,才正式將資源分配給進程;否則本次試探分配作廢,恢復原來的資源分配狀態,讓該進程等待。
(5)用do{…}while 循環語句實現輸入字元y/n判斷是否繼續進行資源申請。
4.安全性檢查演算法(safe()函數)
(1)設置兩個向量:
工作向量Work,它表示系統可提供給進程繼續運行所需的各類資源數目,在執行安全性演算法開始時,Work= Available。
Finish,它表示系統是否有足夠的資源分配給進程,使之運行完成。開始時先做Finish[i]=0;當有足夠的資源分配給進程時,再令Finish[i]=1。
(2)在進程中查找符合以下條件的進程:
條件1:Finish[i]=0;
條件2:need[i][j]<=Work[j]
若找到,則執行步驟(3)否則,執行步驟(4)
(3)當進程獲得資源後,可順利執行,直至完成,並釋放出分配給它的資源,故應執行:
Work[j]= Work[j]+ Allocation[i][j];
Finish[i]=1;
goto step 2;
(4)如果所有的Finish[i]=1都滿足,則表示系統處於安全狀態,否則,處於不安全狀態。
五、源程序結構分析及代碼實現
1.程序結構
程序共有以下五個部分:
(1).初始化chushihua():用於程序開始進行初始化輸入數據:進程數量、資源種類、各種資源可利用數量、各進程的各種資源已分配數量、各進程對各類資源最大需求數等。
(2).當前安全性檢查safe():用於判斷當前狀態安全性,根據不同地方的調用提示處理不同。
(3).銀行家演算法bank():進行銀行家演算法模擬實現的模塊,調用其他各個模塊進行銀行家演算法模擬過程。
(4).顯示當前狀態show():顯示當前資源分配詳細情況,包括:各種資源的總數量(all)、系統目前各種資源可用的數量、各進程已經得到的資源數量、各進程還需要的資源量。
(5).主程序main()
逐個調用初始化、顯示狀態、安全性檢查、銀行家演算法函數,使程序有序的進行。
2.數據結構
程序使用的全局變數:
const int x=10,y=10; //定義常量
int Available[x]; //各種資源可利用的數量
int Allocation[y][y]; //各進程當前已分配的資源數量
int Max[y][y]; //各進程對各類資源的最大需求數
int Need[y][y]; //還需求矩陣
int Request[x]; //申請各類資源的數量
int Work[x]; //工作向量,表系統可提供給進程運行所需各類資源數量
int Finish[y]; //表系統是否有足夠的資源分配給進程,0為否,1為是
int p[y]; //存儲安全序列
int i,j; //全局變數,主要用於循環語句中
int n,m; //n為進程的數量,m為資源種類數
int l=0,counter=0;
3.函數聲明
void chushihua(); //系統初始化函數
void safe(); //安全性演算法函數
void bank(); //銀行家演算法函數
void show (); //輸出當前資源分配情況
4.主函數main()
int main()
{
cout<<…… //顯示程序開始提示信息
chushihua(); //初始化函數調用
cout<<endl<<endl;
showdata(); //輸出初始化後的狀態
//===判斷當前狀態的安全性===
safe(); //安全性演算法函數調用
if (l<n){
cout<<"\n當前狀態不安全,無法申請,程序退出!!!!!"<<endl;
cout<<endl;
system("pause");
sign(); //調用簽名函數
return 0; // break;
}
else{
int i; //局部變數
l=0;
cout<<"\n安全的狀態!!!"<<endl;
cout<<"安全序列為: ";
cout<<endl<<"進程"<<"("<<p[0]<<")"; //輸出安全序列,考慮顯示格式,先輸出第一個
for (i=1; i<n; i++){
cout<<"==>>"<<"進程"<<"("<<p[i]<<")";
}
for (i=0; i<n; i++) Finish[i]=0; //所有進程置為未分配狀態
cout<<endl<<endl;
}
bank(); //銀行家演算法函數調用
return 0;
}
5. 操作系統銀行家演算法流程圖:
2.源程序代碼:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定義全局變數
const int x=10,y=10; //常量,便於修改
int Available[x]; //各資源可利用的數量
int Allocation[y][y]; //各進程當前已分配的資源數量
int Max[y][y]; //各進程對各類資源的最大需求數
int Need[y][y]; //尚需多少資源
int Request[x]; //申請多少資源
int Work[x]; //工作向量,表示系統可提供給進程繼續運行所需的各類資源數量
int Finish[y]; //表示系統是否有足夠的資源分配給進程,1為是
int p[y]; //存儲安全序列
int i,j; //i表示進程,j表示資源
int n,m; //n為進程i的數量,m為資源j種類數
int l=0; //l用來記錄有幾個進程是Finish[i]=1的,當l=n是說明系統狀態是安全的
int counter=0;
//函數聲明
void chushihua(); //初始化函數
void safe(); //安全性演算法
void show(); //函數show,輸出當前狀態
void bank(); //銀行家演算法
void jieshu(); //結束函數
void chushihua()
{
cout<<"輸入進程的數量: ";//從此開始輸入有關數據
cin>>n;
cout<<"輸入資源種類數: ";
cin>>m;
cout<<endl<<"輸入各種資源當前可用的數量( "<<m<<" 種): "<<endl;
for (j=0; j<m; j++)
{
cout<<"輸入資源 "<<j<<" 可利用的數量Available["<<j<<"]: ";
cin>>Available[j]; //輸入數字的過程...
Work[j]=Available[j]; //初始化Work[j],它的初始值就是當前可用的資源數
}
cout<<endl<<"輸入各進程當前已分配的資源數量Allocation["<<n<<"]["<<m<<"]: "<<endl;
for (i=0; i<n; i++)
{
for (j=0; j<m; j++)
{
cout<<" 輸入進程 "<<i<<" 當前已分配的資源 "<<j<<" 數量: ";
cin>>Allocation[i][j];
}
cout<<endl;
Finish[i]=0;//初始化Finish[i]
}
cout<<endl<<"輸入各進程對各類資源的最大需求Max["<<n<<"]["<<m<<"]: "<<endl;
for (i=0; i<n; i++)
{
for (j=0; j<m; j++)
{
cout<<" 輸入進程 "<<i<<" 對資源 "<<j<<" 的最大需求數: ";
cin>>Max[i][j];
if(Max[i][j]>=Allocation[i][j]) //若最大需求大於已分配,則計算需求量
Need[i][j] = Max[i][j]-Allocation[i][j];
else
Need[i][j]=0;//Max小於已分配的時候,此類資源已足夠不需再申請
}
cout<<endl;
}
cout<<endl<<"初始化完成"<<endl;
}
//安全性演算法函數
void safe()
{
l=0;
for (i=0; i<n;i++)
{ //i++
if (Finish[i]==0)
{ //逐個查找Finish[i]==0的進程 條件一
counter=0; //記數器
for (j=0; j<m; j++)
{
if (Work[j]>=Need[i][j]) counter=counter+1;//可用大於需求,記數
}
if(counter==m) //i進程的每類資源都符合Work[j]>=Need[i][j] 條件二
{
p[l]=i; //存儲安全序列
Finish[i]=1; //i進程標志為可分配
for (j=0; j<m;j++)
Work[j]=Work[j]+Allocation[i][j]; //釋放資源
l=l+1; //記數,現在有L個進程是安全的,當L=N時說明滿足安全序列
i= -1; //從第一個進程開始繼續尋找滿足條件一二的進程
}
}
}
}
//顯示當前狀態函數
void show() //函數show,輸出當前資源分配情況
{
int i,j; //局部變數
int All[y]; //各種資源的總數量
int L1; //局部變數L1
cout<<"當前的狀態為:"<<endl;
cout<<"各種資源的總數量:"<<endl;
for (j=0;j<m;j++)
{
cout<<" 資源"<<j<<": ";
All[j]=Available[j]; //總數量=可用的+已分配的
for (i=0;i<n;i++) All[j]+=Allocation[i][j];
cout<<All[j]<<" ";
}
cout<<endl<<"當前各種資源可用的量為(available):"<<endl;
for (j=0;j<m;j++)
cout<<" 資源"<<j<<": "<<Available[j]<<" ";
cout<<endl<<"各進程已經得到的資源量(allocation): "<<endl;
for(i=0;i<=m;i++)
{
for (j=i;j<m;j++) cout<<" 資源"<<j;
cout<<endl;
for(L1=0;L1<n;L1++)
{
cout<<"進程"<<L1<<":";
for (j=i;j<m;j++) cout<<Allocation[L1][j]<<" ";
cout<<endl;
}
}
cout<<endl<<"各進程還需要的資源量(need):"<<endl;
for(i=0;i<=m;i++)
{
for (j=i;j<m;j++) cout<<" 資源"<<j;
cout<<endl;
for(L1=0;L1<n;L1++)
{
cout<<"進程"<<L1<<":";
for (j=i;j<m;j++) cout<<Need[L1][j]<<" ";
cout<<endl;
}
}
}
//銀行家演算法函數
void bank()
{
cout<<endl<<"進程申請分配資源:"<<endl;
int k=0; //用於輸入進程編號
bool r=false; // 初值為假,輸入Y繼續申請則置為真
do{//輸入請求
cout<<"輸入申請資源的進程(0-"<<n-1<<"): ";
cin>>k;
cout<<endl;
while(k>n-1) //輸入錯誤處理
{
cout<<endl<<"輸入錯誤,重新輸入:"<<endl;
cout<<endl<<"輸入申請資源的進程(0--"<<n-1<<"): ";
cin>>k;
cout<<endl;
}
cout<<endl<<"輸入該進程申請各類資源的數量: "<<endl;
for (j=0; j<m; j++)
{
do{ //do……while 循環判斷申請輸入的情況
cout<<"進程 "<<k<<" 申請資源["<<j<<"]的數量:";
cin>>Request[j];
cout<<endl;
if(Request[j]>Need[k][j]){ //申請大於需求量時出錯,提示重新輸入(貸款數目不允許超過需求數目)
cout<<"申請大於需要量!"<<endl;
cout<<"申請的資源"<<j<<"的數量為"<<Request[j]<<",大於進程"<<k<<"對該資源需求量"<<Need[k][j]<<"。"<<endl;
cout<<"重新輸入!"<<endl;
}
else //先判斷是否申請大於需求量,再判斷是否申請大於可利用量
if(Request[j]>Available[j]){ //申請大於可利用量, 應該阻塞等待?…… ???
cout<<"\n沒有那麼多資源,目前可利用資源"<<j<<"數量為"<<Available[j]<<",本次申請不成功,進程等待!"<<endl;
Finish[k]=0; //該進程等待
goto ppp; //goto語句 跳轉,結束本次申請
}
}while(Request[j]>Need[k][j]); //Request[j]>Available[j]||
}
//改變Avilable、Allocation、Need的值
for (j=0; j<m; j++) {
Available[j] = Available[j]-Request[j];
Allocation[k][j] = Allocation[k][j]+Request[j];
Need[k][j] = Need[k][j]-Request[j];
Work[j] = Available[j];
}
//判斷當前狀態的安全性
safe(); //調用安全性演算法函數
if (l<n)
{
l=0;
cout<<"\n試分配後,狀態不安全,所以不予分配!恢復原狀態"<<endl;
//恢復數據
for (j=0; j<m; j++)
{
Available[j] = Available[j]+Request[j];
Allocation[k][j] = Allocation[k][j]-Request[j];
Need[k][j] = Need[k][j]+Request[j];
Work[j] = Available[j];
}
for (i=0; i<n; i++)
Finish[i]=0; //進程置為未分配狀態
}
else
{
l=0;
cout<<"\n申請資源成功!!!"<<endl;
for(j=0;j<m;j++)
{
if(Need[k][j]==0);
else { //有一種資源還沒全部申請到,則該進程不可執行,不能釋放擁有的資源
l=1; //置l為1,作為判斷標志
break;
}
}
if(l!=1){ //進程可以執行,則釋放該進程的所有資源
for (j=0;j<m;j++){
Available[j]=Available[j]+Allocation[k][j];
Allocation[k][j]=0;
}
cout<<"該進程已得到所有需求資源,執行後將釋放其所有擁有資源!"<<endl;
}
l=0; //歸零
cout<<"\n安全的狀態!"<<endl;
cout<<"安全序列為: ";
cout<<endl<<"進程"<<"("<<p[0]<<")"; //輸出安全序列,考慮顯示格式,先輸出第一個
Finish[0]=0;
for (i=1; i<n; i++){
cout<<"==>>"<<"進程"<<"("<<p[i]<<")";
Finish[i]=0; //所有進程置為未分配狀態
}
cout<<endl<<endl;
}
show(); //顯示當前狀態
ppp: //申請大於可利用量, 應該阻塞等待,結束本次資源申請,GOTO 語句跳轉至此
cout<<endl<<"是否繼續申請資源(y/n) ?";
char* b=new char; //輸入y/n,判斷是否繼續申請 <<endl
cin>>b;
cout<<endl;
cout<<"-------------------------------------------"<<endl<<endl;
cout<<endl;
if(*b=='y'||*b=='Y')
r=true;
else{
r=false; //輸入非 Y 則令 R =false
jieshu(); //調用結束函數
}
} while (r==true);
}
//結束函數
void jieshu()
{
cout<<endl<<endl;
cout<<"\t\t 演示計算完畢"<<endl;
cout<<endl<<endl;
}
//主函數
int main()
{
cout<<endl<<endl<<"\t\t\t\t模擬銀行家演算法"<<endl<<endl;
chushihua(); //初始化函數調用
cout<<endl;
show(); //輸出當前狀態
safe(); //判斷當前狀態的安全性
if (l<n) //l在safe中是用來記錄安全的進程的個數的
{
cout<<"\n當前狀態不安全,拒絕申請!"<<endl;
cout<<endl;
return 0;
}
else
{
int i; //局部變數
l=0;
cout<<endl<<"\n當前的狀態是安全的!安全序列為:"<<endl;
cout<<"進程"<<"("<<p[0]<<")"; //輸出安全序列
for (i=1; i<n; i++) cout<<"->>"<<"進程"<<"("<<p[i]<<")";
for (i=0; i<n; i++) Finish[i]=0; //所有進程置為未分配狀態
cout<<endl;
}
bank(); //調用銀行家演算法函數
cout<<"\t\t 演示計算完畢"<<endl;
return 0;
}
運行結果:
1.初始化結果
2.檢測系統資源分配是否安全結果:
六、課程設計的總結
操作系統的基本特徵是並發與共享。系統允許多個進程並發執行,並且共享系統的軟、硬體資源。為了最大限度的利用計算機系統的資源,操作系統應採用動態分配的策略,但是這樣就容易因資源不足,分配不當而引起「死鎖」。而我本次課程設計就是得用銀行家演算法來避免「死鎖」。銀行家演算法就是一個分配資源的過程,使分配的序列不會產生死鎖。此演算法的中心思想是:按該法分配資源時,每次分配後總存在著一個進程,如果讓它單獨運行下去,必然可以獲得它所需要的全部資源,也就是說,它能結束,而它結束後可以歸還這類資源以滿足其他申請者的需要。
本次程序就是按照上面的思路展開的。但是因為時間上的倉促,本課程設計的存在著以下不足:一、不能實現並發操作,即當總資源同時滿足幾個進程所需要的資源數時,這些進程不能同時進行,只能一一按進程順序執行。二、掃描進程順序單一,只能按進程到來的順序(即編號)來掃描,從而產生的安全順序只能是在這個順序的基礎上產生的,而其實安全順序是有多個的。三、對進程數和資源數進行的數量進行了限制,都只能最多有十個。四、運行程序後,界面較差,進程數,所需要資源數,已分配資源數,能用資源數,不能一目瞭然。
這次課程設計時間上雖說倉促點,但是我依然學到了很多的實用性知識。除了更深的了解這個演算法,而且對C語言進行了復習,而且其過程中有很多的知識點都不記得了,所以在此感謝在此過程中幫助過我的老師和同學。
最後的感悟就是:只要你親自動手,你就能學到知識。
再次感謝幫助過我的老師和同學!
『肆』 操作系統銀行家演算法
銀行家演算法是根據一個進程序列的請求試探性地分配資源給,即在避免死鎖方法中允許進程動態地申請資源,但系統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。
這里系統一步一步的試探性分配資源給每個進程,
對於每一個進程Pi(1≤i≤n),它以後尚需要的資源量沒有超過系統當前剩餘資源量與所有進程Pj (j<i )當前佔有資源量之和。
所以他是安全序列。
『伍』 關於銀行家演算法一個簡單的問題
按照你的做法,如果這時候系統給進程1一個資源,給進程2一個資源,
那樣系統就會死鎖。而你們老師說的就是正確的,因為無論系統把那一個
資源給任意一個進程,任意一個進程都會完成並釋放資源。
『陸』 銀行家演算法 操作系統課程設計
這個剛做過,直接貼給你好了,給分吧
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#define False 0
#define True 1
int Max[100][100]={0};//各進程所需各類資源的最大需求
int Avaliable[100]={0};//系統可用資源
char name[100]={0};//資源的名稱
int Allocation[100][100]={0};//系統已分配資源
int Need[100][100]={0};//還需要資源
int Request[100]={0};//請求資源向量
int temp[100]={0};//存放安全序列
int Work[100]={0};//存放系統可提供資源
int M=100;//作業的最大數為100
int N=100;//資源的最大數為100
void showdata()//顯示資源矩陣
{
int i,j;
cout<<"系統目前可用的資源[Avaliable]:"<<endl;
for(i=0;i<N;i++)
cout<<name[i]<<" ";
cout<<endl;
for (j=0;j<N;j++)
cout<<Avaliable[j]<<" ";//輸出分配資源
cout<<endl;
cout<<" Max Allocation Need"<<endl;
cout<<"進程名 ";
for(j=0;j<3;j++){
for(i=0;i<N;i++)
cout<<name[i]<<" ";
cout<<" ";
}
cout<<endl;
for(i=0;i<M;i++){
cout<<" "<<i<<" ";
for(j=0;j<N;j++)
cout<<Max[i][j]<<" ";
cout<<" ";
for(j=0;j<N;j++)
cout<<Allocation[i][j]<<" ";
cout<<" ";
for(j=0;j<N;j++)
cout<<Need[i][j]<<" ";
cout<<endl;
}
}
int changdata(int i)//進行資源分配
{
int j;
for (j=0;j<M;j++) {
Avaliable[j]=Avaliable[j]-Request[j];
Allocation[i][j]=Allocation[i][j]+Request[j];
Need[i][j]=Need[i][j]-Request[j];
}
return 1;
}
int safe()//安全性演算法
{
int i,k=0,m,apply,Finish[100]={0};
int j;
int flag=0;
Work[0]=Avaliable[0];
Work[1]=Avaliable[1];
Work[2]=Avaliable[2];
for(i=0;i<M;i++){
apply=0;
for(j=0;j<N;j++){
if (Finish[i]==False&&Need[i][j]<=Work[j]){
apply++;
if(apply==N){
for(m=0;m<N;m++)
Work[m]=Work[m]+Allocation[i][m];//變分配數
Finish[i]=True;
temp[k]=i;
i=-1;
k++;
flag++;
}
}
}
}
for(i=0;i<M;i++){
if(Finish[i]==False){
cout<<"系統不安全"<<endl;//不成功系統不安全
return -1;
}
}
cout<<"系統是安全的!"<<endl;//如果安全,輸出成功
cout<<"分配的序列:";
for(i=0;i<M;i++){//輸出運行進程數組
cout<<temp[i];
if(i<M-1) cout<<"->";
}
cout<<endl;
return 0;
}
void share()//利用銀行家演算法對申請資源對進行判定
{
char ch;
int i=0,j=0;
ch='y';
cout<<"請輸入要求分配的資源進程號(0-"<<M-1<<"):";
cin>>i;//輸入須申請的資源號
cout<<"請輸入進程 "<<i<<" 申請的資源:"<<endl;
for(j=0;j<N;j++)
{
cout<<name[j]<<":";
cin>>Request[j];//輸入需要申請的資源
}
for (j=0;j<N;j++){
if(Request[j]>Need[i][j])//判斷申請是否大於需求,若大於則出錯
{
cout<<"進程 "<<i<<"申請的資源大於它需要的資源";
cout<<" 分配不合理,不予分配!"<<endl;
ch='n';
break;
}
else {
if(Request[j]>Avaliable[j])//判斷申請是否大於當前資源,若大於則
{ //出錯
cout<<"進程"<<i<<"申請的資源大於系統現在可利用的資源";
cout<<" 分配出錯,不予分配!"<<endl;
ch='n';
break;
}
}
}
if(ch=='y') {
changdata(i);//根據進程需求量變換資源
showdata();//根據進程需求量顯示變換後的資源
safe();//根據進程需求量進行銀行家演算法判斷
}
}
void addresources(){//添加資源
int n,flag;
cout<<"請輸入需要添加資源種類的數量:";
cin>>n;
flag=N;
N=N+n;
for(int i=0;i<n;i++){
cout<<"名稱:";
cin>>name[flag];
cout<<"數量:";
cin>>Avaliable[flag++];
}
showdata();
safe();
}
void delresources(){//刪除資源
char ming;
int i,flag=1;
cout<<"請輸入需要刪除的資源名稱:";
do{
cin>>ming;
for(i=0;i<N;i++)
if(ming==name[i]){
flag=0;
break;
}
if(i==N)
cout<<"該資源名稱不存在,請重新輸入:";
}
while(flag);
for(int j=i;j<N-1;j++)
{
name[j]=name[j+1];
Avaliable[j]=Avaliable[j+1];
}
N=N-1;
showdata();
safe();
}
void changeresources(){//修改資源函數
cout<<"系統目前可用的資源[Avaliable]:"<<endl;
for(int i=0;i<N;i++)
cout<<name[i]<<":"<<Avaliable[i]<<endl;
cout<<"輸入系統可用資源[Avaliable]:"<<endl;
cin>>Avaliable[0]>>Avaliable[1]>>Avaliable[2];
cout<<"經修改後的系統可用資源為"<<endl;
for (int k=0;k<N;k++)
cout<<name[k]<<":"<<Avaliable[k]<<endl;
showdata();
safe();
}
void addprocess(){//添加作業
int flag=M;
M=M+1;
cout<<"請輸入該作業的最打需求量[Max]"<<endl;
for(int i=0;i<N;i++){
cout<<name[i]<<":";
cin>>Max[flag][i];
Need[flag][i]=Max[flag][i]-Allocation[flag][i];
}
showdata();
safe();
}
int main()//主函數
{
int i,j,number,choice,m,n,flag;
char ming;
cout<<"*****************資源管理系統的設計與實現*****************"<<endl;
cout<<"請首先輸入系統可供資源種類的數量:";
cin>>n;
N=n;
for(i=0;i<n;i++)
{
cout<<"資源"<<i+1<<"的名稱:";
cin>>ming;
name[i]=ming;
cout<<"資源的數量:";
cin>>number;
Avaliable[i]=number;
}
cout<<endl;
cout<<"請輸入作業的數量:";
cin>>m;
M=m;
cout<<"請輸入各進程的最大需求量("<<m<<"*"<<n<<"矩陣)[Max]:"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>Max[i][j];
do{
flag=0;
cout<<"請輸入各進程已經申請的資源量("<<m<<"*"<<n<<"矩陣)[Allocation]:"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n;j++){
cin>>Allocation[i][j];
if(Allocation[i][j]>Max[i][j])
flag=1;
Need[i][j]=Max[i][j]-Allocation[i][j];
}
if(flag)
cout<<"申請的資源大於最大需求量,請重新輸入!\n";
}
while(flag);
showdata();//顯示各種資源
safe();//用銀行家演算法判定系統是否安全
while(choice)
{
cout<<"**************銀行家演算法演示***************"<<endl;
cout<<" 1:增加資源 "<<endl;
cout<<" 2:刪除資源 "<<endl;
cout<<" 3:修改資源 "<<endl;
cout<<" 4:分配資源 "<<endl;
cout<<" 5:增加作業 "<<endl;
cout<<" 0:離開 "<<endl;
cout<<"*******************************************"<<endl;
cout<<"請選擇功能號:";
cin>>choice;
switch(choice)
{
case 1: addresources();break;
case 2: delresources();break;
case 3: changeresources();break;
case 4: share();break;
case 5: addprocess();break;
case 0: choice=0;break;
default: cout<<"請正確選擇功能號(0-5)!"<<endl;break;
}
}
return 1;
}
『柒』 銀行家演算法
什麼是銀行家演算法:
銀行家演算法是一種最有代表性的避免死鎖的演算法。在避免死鎖方法中允許進程動態地申請資源,但系統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。為實現銀行家演算法,系統必須設置若干數據結構。
要解釋銀行家演算法,必須先解釋操作系統安全狀態和不安全狀態。
安全序列是指一個進程序列{P1,…,Pn}是安全的,如果對於每一個進程Pi(1≤i≤n),它以後尚需要的資源量不超過系統當前剩餘資源量與所有進程Pj (j < i )當前佔有資源量之和。
安全狀態
如果存在一個由系統中所有進程構成的安全序列P1,…,Pn,則系統處於安全狀態。安全狀態一定是沒有死鎖發生。
不安全狀態
不存在一個安全序列。不安全狀態不一定導致死鎖。
原理:
我們可以把操作系統看作是銀行家,操作系統管理的資源相當於銀行家管理的資金,進程向操作系統請求分配資源相當於用戶向銀行家貸款。
為保證資金的安全,銀行家規定:
(1) 當一個顧客對資金的最大需求量不超過銀行家現有的資金時就可接納該顧客;
(2) 顧客可以分歧貸款,但貸款的總數不能超過最大需求量;
(3) 當銀行家現有的資金不能滿足顧客尚需的貸款數額時,對顧客的貸款可推遲支付,但總能使顧客在有限的時間里得到貸款;
(4) 當顧客得到所需的全部資金後,一定能在有限的時間里歸還所有的資金.
操作系統按照銀行家制定的規則為進程分配資源,當進程首次申請資源時,要測試該進程對資源的最大需求量,如果系統現存的資源可以滿足它的最大需求量則按當前的申請量分配資源,否則就推遲分配。當進程在執行中繼續申請資源時,先測試該進程已佔用的資源數與本次申請的資源數之和是否超過了該進程對資源的最大需求量。若超過則拒絕分配資源,若沒有超過則再測試系統現存的資源能否滿足該進程尚需的最大資源量,若能滿足則按當前的申請量分配資源,否則也要推遲分配。
程序舉例:
已知進程{P0,P1,P2,P3,P4},有三類系統資源A、B、C的數量分別為10、5、7,在T0時刻的資源
(1)若進程P1請求資源,發出請求向量Request1(1,0,2),編寫程序用銀行家演算法判斷系統能否將資源分配給它;
(2)若進程P2提出請求Request(0,1,0),用銀行家演算法程序驗證系統能否將資源分配給它。
程序代碼:
P1進程提出的請求,可以分配。
P2進程不能分配,因為請求的B類資源超過了它的最大值。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 50
void main()
{
unsigned int Available[MAXSIZE]; //可利用資源向量
unsigned int Max[MAXSIZE][MAXSIZE]; //最大需求矩陣
unsigned int Allocation[MAXSIZE][MAXSIZE]; //已分配矩陣
unsigned int Need[MAXSIZE][MAXSIZE]; //需求矩陣
unsigned int Request[MAXSIZE]; //請求向量
unsigned int Work[MAXSIZE]; //工作向量
bool Finish[MAXSIZE]; //是否有足夠資源分配給進程,使之運行完成
unsigned int SafeSequence[MAXSIZE]; //安全序列
int i,j;
int p; //請求資源的進程的下標
int temp = 0; //安全序列下標
int total = 0;
int N;
int M;
printf("請輸入進程數N=");
scanf("%d",&N);
printf("請輸入資源種類數M=");
scanf("%d",&M);
//用戶輸入數據,初始化Available數組
printf("初始化可用資源數組:\n");
for(i=0; i<M; i++)
{
printf("\t%c類資源:",65+i);
scanf("%d",&Available[i]);
}
//用戶輸入數據,初始化Max數組
printf("初始化最大需求數組:\n");
for(i=0; i<N; i++)
{
printf("\tP%d進程最大需要\n",i);
for(j=0; j<M; j++)
{
printf("\t\t%c類資源:",65+j);
scanf("%d",&Max[i][j]);
}
}
//用戶輸入數據,初始化Allocation數組
printf("初始化已分配資源數組:\n");
for(i=0; i<N; i++)
{
printf("\tP%d進程已分配\n",i);
for(j=0; j<M; j++)
{
printf("\t\t%c類資源:",65+j);
scanf("%d",&Allocation[i][j]);
}
}
//初始化Need數組
for(i=0; i<N; i++)
for(j=0; j<M; j++)
{
Need[i][j] = Max[i][j] - Allocation[i][j];
}
//進程發出資源請求後檢查
do
{
printf("資源請求:\n");
printf("\t輸入請求資源的進程下標:");
scanf("%d",&p);
printf("\t進程P%d請求\n",p);
//初始化請求向量
for(i=0; i<M; i++)
{
printf("\t\t%c類資源:",65+i);
scanf("%d",&Request[i]);
}
for(i=0; i<M; i++) //檢查Request <= Need ?
if(Request[i] > Need[p][i])
{
printf("\t請求的%c類資源數超過它所宣布的最大值!\n",65+i);
break;
}
if(i == M) //通過上層檢查,繼續檢查Request <= Available ?
{
for(i=0; i<M; i++)
if(Request[i] > Available[i])
{
printf("\t尚無足夠%c類資源,P%d須等待!\n",65+i,p);
break;
}
}
if(i == M) //嘗試分配
{
for(i=0; i<M; i++)
{
Available[i] -= Request[i];
Allocation[p][i] += Request[i];
Need[p][i] -= Request[i];
}
}
}while(i<M);
//初始化Work,Finish向量
for(i=0; i<M; i++)
{
Work[i] = Available[i];
}
for(i=0; i<N; i++)
{
Finish[i] = false;
}
//安全性演算法
do
{
total = temp;
for(i=0; i<N; i++)
{
if(Finish[i] == false)
{
for(j=0; j<M; j++)
if(Need[i][j] > Work[j])
{
break;
}
if(j == M) //各類資源都滿足Need <= Work
{
for(j=0; j<M; j++)
{
Work[j] += Allocation[i][j]; //釋放資源
}
Finish[i] = true;
SafeSequence[temp++] = i; //加入安全序列
}
}
}
}while(total != temp); //所有進程檢查一遍之後,如果安全序列有變化,則進行下一輪
//否則說明所有的Finish都為true,或者因沒有安全序列退出循環
if(temp == N)
{
printf("安全序列:");
for(temp=0; temp<N; temp++)
{
printf("P%d ",SafeSequence[temp]);
}
}
else
{
printf("系統處於不安全狀態!不能分配!\n");
}
getchar();
getchar();
}
這個程序還行,輸入有點麻煩,我自己編寫的是用文件輸入系統描述信息的,但是缺少說明,怕你搞不明白。希望對你有所幫助!
『捌』 進程同步及銀行家演算法的模擬實現 有會的大俠們幫幫忙吧 這個要求實在是太多 不太懂 答的好的追100
銀行家演算法=-- -
1. 安全狀態: 在某時刻系統中所有進程可以排列一個安全序列:,剛稱此時,系統是安全的.
所謂安全序列是指對於P2,都有它所需要剩餘資源數量不大於系統掌握的剩餘的空間資源與所有Pi(j<i)所佔的資源之和.
2.不安全狀態可能產生死鎖.
目前狀態 最大需求 尚需
P1 3 9 6
P2 5 10 5
P3 2 4 2
在每一次進程中申請的資源,判定一下,若實際分配的話,之後系統是否安全.
3.銀行家演算法的思路:
1),進程一開始向系統提出最大需求量.
2),進程每次提出新的需求(分期貸款)都統計是否超出它事先提出的最大需求量.
3),若正常,則判斷該進程所需剩餘剩餘量(包括本次申請)是否超出系統所掌握的
剩餘資源量,若不超出,則分配,否則等待.
4.銀行家演算法的數據結構.
1),系統剩餘資源量A[n],其中A[n]表示第I類資源剩餘量.
2),各進程最大需求量,B[m][n],其中B[j][i]表示進程j對i
類資源最大需求.
3),已分配資源量C[m][n],其中C[j][i]表示系統j程已得到的第i資源的數量.
4),剩餘需求量.D[m][n],其中D[j][i]對第i資源尚需的數目.
5.銀行家演算法流程:當某時刻,某進程時,提出新的資源申請,系統作以下操作:
1),判定E[n]是否大於D[j][n],若大於,表示出錯.
2),判定E[n]是否大於系統剩餘量A[n],若大於,則該進程等待.
3),若以上兩步沒有問題,嘗試分配,即各變數作調整.
4),按照安全性推測演算法,判斷,分配過後,系統是否安全,若安全,則實際分配,否則,撤消分配,讓進程等待.
6."安全性檢測"演算法
1),先定義兩個變數,用來表示推算過程的數據.
F[n]=A[n],表示推算過程中,系統中剩餘資源量的變化.
J[n]=False表示推算過程中各進程是否假設"已完成"
2),流程:
在"剩餘"的進程中(在推算)過程中,一些進程假設已完成,查找D[j][n]<=F[n]的進程,找到後令J[j]=True
(假設該進程完成),F[n]+D[j][n](該進程所佔資源釋放),如此循環執行.
若最後,所有的F[n]=True(在推算過程中,所有進程均可以完成),則表示(分配過後)系統是安全的,否則系統是不安全的.
#include "malloc.h"
#include "stdio.h"
#define alloclen sizeof(struct allocation)
#define maxlen sizeof(struct max)
#define avalen sizeof(struct available)
#define needlen sizeof(struct need)
#define finilen sizeof(struct finish)
#define pathlen sizeof(struct path)
struct allocation
{
int value;
struct allocation *next;
};
struct max
{
int value;
struct max *next;
};
struct available
{
int value;
struct available *next;
};
struct need
{
int value;
struct need *next;
};
struct path
{
int value;
struct path *next;
};
struct finish
{
int stat;
struct finish *next;
};
int main()
{
int row,colum,status=0,i,j,t,temp,processtest;
struct allocation *allochead,*alloc1,*alloc2,*alloctemp;
struct max *maxhead,*maxium1,*maxium2,*maxtemp;
struct available *avahead,*available1,*available2,*availabletemp,*workhead,*work1,*work2,*worktemp,*worktemp1;
struct need *needhead,*need1,*need2,*needtemp;
struct finish *finihead,*finish1,*finish2,*finishtemp;
struct path *pathhead,*path1,*path2,*pathtemp;
char c;
printf("\nPlease enter the type of sources the system has:\n");
scanf("%d",&colum);
printf("Please enter the number of processes now in the memory:\n");
scanf("%d",&row);
printf("Please enter the allocation array:\n");
for(i=0;i<row;i++)
{
printf("The allocation for process p%d:\n",i);
for (j=0;j<colum;j++)
{
printf("The type %c system resource allocated:\n",'A'+j);
if(status==0)
{
allochead=alloc1=alloc2=(struct allocation*)malloc(alloclen);
alloc1->next=alloc2->next=NULL;
scanf("%d",&allochead->value);
status++;
}
else
{
alloc2=(struct allocation *)malloc(alloclen);
scanf("%d,%d",&alloc2->value);
if(status==1)
{
allochead->next=alloc2;
status++;
}
alloc1->next=alloc2;
alloc1=alloc2;
}
}
}
alloc2->next=NULL;
status=0;
printf("Please enter the max array:\n");
for(i=0;i<row;i++)
{
printf("The max needed from process p%d:\n",i);
for (j=0;j<colum;j++)
{
printf("The type %c maxium system resource may needed:\n",'A'+j);
if(status==0)
{
maxhead=maxium1=maxium2=(struct max*)malloc(maxlen);
maxium1->next=maxium2->next=NULL;
scanf("%d",&maxium1->value);
status++;
}
else
{
maxium2=(struct max *)malloc(maxlen);
scanf("%d,%d",&maxium2->value);
if(status==1)
{
maxhead->next=maxium2;
status++;
}
maxium1->next=maxium2;
maxium1=maxium2;
}
}
}
maxium2->next=NULL;
status=0;
printf("Please enter the available array now exists in the system:\n");
for (j=0;j<colum;j++)
{
printf("The type %c available system resource number:\n",'A'+j);
if(status==0)
{
avahead=available1=available2=(struct available*)malloc(avalen);
workhead=work1=work2=(struct available*)malloc(avalen);
available1->next=available2->next=NULL;
work1->next=work2->next=NULL;
scanf("%d",&available1->value);
work1->value=available1->value;
status++;
}
else
{
available2=(struct available*)malloc(avalen);
work2=(struct available*)malloc(avalen);
scanf("%d,%d",&available2->value);
work2->value=available2->value;
if(status==1)
{
avahead->next=available2;
workhead->next=work2;
status++;
}
available1->next=available2;
available1=available2;
work1->next=work2;
work1=work2;
}
}
available2->next=NULL;
work2->next=NULL;
status=0;
alloctemp=allochead;
maxtemp=maxhead;
for(i=0;i<row;i++)
for (j=0;j<colum;j++)
{
if(status==0)
{
needhead=need1=need2=(struct need*)malloc(needlen);
need1->next=need2->next=NULL;
need1->value=maxtemp->value-alloctemp->value;
status++;
}
else
{
need2=(struct need *)malloc(needlen);
need2->value=(maxtemp->value)-(alloctemp->value);
if(status==1)
{
needhead->next=need2;
status++;
}
need1->next=need2;
need1=need2;
}
maxtemp=maxtemp->next;
alloctemp=alloctemp->next;
}
need2->next=NULL;
status=0;
for(i=0;i<row;i++)
{
if(status==0)
{
finihead=finish1=finish2=(struct finish*)malloc(finilen);
finish1->next=finish2->next=NULL;
finish1->stat=0;
status++;
}
else
{
finish2=(struct finish*)malloc(finilen);
finish2->stat=0;
if(status==1)
{
finihead->next=finish2;
status++;
}
finish1->next=finish2;
finish1=finish2;
}
}
finish2->next=NULL; /*Initialization compleated*/
status=0;
processtest=0;
for(temp=0;temp<row;temp++)
{
alloctemp=allochead;
needtemp=needhead;
finishtemp=finihead;
worktemp=workhead;
for(i=0;i<row;i++)
{
worktemp1=worktemp;
if(finishtemp->stat==0)
{
for(j=0;j<colum;j++,needtemp=needtemp->next,worktemp=worktemp->next)
if(needtemp->value<=worktemp->value)
processtest++;
if(processtest==colum)
{
for(j=0;j<colum;j++)
{
worktemp1->value+=alloctemp->value;
worktemp1=worktemp1->next;
alloctemp=alloctemp->next;
}
if(status==0)
{
pathhead=path1=path2=(struct path*)malloc(pathlen);
path1->next=path2->next=NULL;
path1->value=i;
status++;
}
else
{
path2=(struct path*)malloc(pathlen);
path2->value=i;
if(status==1)
{
pathhead->next=path2;
status++;
}
path1->next=path2;
path1=path2;
}
finishtemp->stat=1;
}
else
{
for(t=0;t<colum;t++)
alloctemp=alloctemp->next;
finishtemp->stat=0;
}
}
else
for(t=0;t<colum;t++)
{
needtemp=needtemp->next;
alloctemp=alloctemp->next;
}
processtest=0;
worktemp=workhead;
finishtemp=finishtemp->next;
}
}
path2->next=NULL;
finishtemp=finihead;
for(temp=0;temp<row;temp++)
{
if(finishtemp->value==0)
{
printf("\nWARNING,the system is in nonsafe status!\n");
exit(0);
}
finishtemp=finishtemp->next;
}
printf("\nThe system is in safe status!\n");
printf("\nThe safe sequence is: \n");
do
{
printf("p%d ",pathhead->value);
}
while(pathhead=pathhead->next);
}
『玖』 什麼是銀行家演算法
銀行家演算法是一種最有代表性的避免死鎖的演算法。在避免死鎖方法中允許進程動態地申請資源,但系 銀行家演算法統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。為實現銀行家演算法,系統必須設置若干
『拾』 銀行家演算法的背景簡介
在銀行中,客戶申請貸款的數量是有限的,每個客戶在第一次申請貸款時要聲明完成該項目所需的最大資金量,在滿足所有貸款要求時,客戶應及時歸還。銀行家在客戶申請的貸款數量不超過自己擁有的最大值時,都應盡量滿足客戶的需要。在這樣的描述中,銀行家就好比操作系統,資金就是資源,客戶就相當於要申請資源的進程。
銀行家演算法是一種最有代表性的避免死鎖的演算法。在避免死鎖方法中允許進程動態地申請資源,但系統在進行資源分配之前,應先計算此次分配資源的安全性,若分配不會導致系統進入不安全狀態,則分配,否則等待。為實現銀行家演算法,系統必須設置若干數據結構。
要解釋銀行家演算法,必須先解釋操作系統安全狀態和不安全狀態。
安全序列是指一個進程序列{P1,…,Pn}是安全的,即對於每一個進程Pi(1≤i≤n),它以後尚需要的資源量不超過系統當前剩餘資源量與所有進程Pj (j < i )當前佔有資源量之和。