博主 q q 656358805 歡迎線上交流。
六、程序的同步與互斥及其訊號量的實現。
程序併發時存在著一些制約關係,可以分為直接制約和間接制約。
直接制約:程序的執行依賴另乙個程序的訊息或訊號。
間接制約:各併發程序的速度受公共資源的約束。
互斥:對於某乙個共有資源,當乙個程序訪問它的時候不許其它程序訪問,其他程序想訪問就必須等待。互斥是用來解決程序的間接制約,這裡提一下臨界資源,臨界資源是一次只能被乙個程序訪問的的資源,在臨界資源的**中分為進入區、臨界區、退出區、剩餘區。
互斥的實現:
1、嚴格輪換法:
int turn=1;
程序一:
while(turn!=1)
/*臨界區*/
turn = 2;
/*剩餘區*/
程序二:
while(turn!=2)
/*臨界區*/
turn=1;
/*剩餘區*/
有嚴重的忙等待,資源利用率太低。
2、peterson演算法。
boolean flag[2]=;
int turn;
程序一:
while(true)
flag[0]=true;
turn=2;
while(flag[1]&&turn=2)
/*臨界區*/
flag[0]=false;
/*剩餘區*/
程序二:
while(true)
flag[1]=true;
turn=1;
while(flag[0]&&turn==1)
/*臨界區*/
flag[1]=false;
/*剩餘區*/
仍然有忙等待,系統資源利用率下降。
同步:兩個或多個程序為了完成同乙個任務,在執行速度或某個時序點上必須相互協調,相互存在依賴。(互斥是不考慮執行順序的同步)
那麼同步和互斥到底如何真正實現呢?
訊號量:一種功能強大的原語。
功能:用來記錄資源個數。
記錄型訊號量:乙個結構體,其中乙個int值表示資源個數,另乙個陣列記錄等待該資源而阻塞的程序。
記錄型訊號量的使用:記錄型訊號量為正值時表示資源的個數,為負值時表示因為等待資源而阻塞的程序的個數。
p/v 操作:
p(up):釋放乙個資源,訊號加一,如果此時訊號量大於0則釋放之前訊號量大於等於零,因此釋放前沒有掛起的程序,繼續執行程序;如果小於等於零,那麼表示之前有掛起的程序,則用喚醒原語喚醒佇列中第乙個程序,然後返回到原程序繼續執行。
v(down):占有乙個資源,訊號減一,如果此時訊號量大於等於0則表示之前大於零,無掛起程序,則繼續進行;如果小於零則表示之前沒有訊號量,此時程序自我阻塞,插入到佇列隊尾。
互斥的實現:將臨界資源夾在v和p操作中。
設定訊號量r
down(r);
/*臨界區*/
up(r);
/*剩餘區*/
同步的實現:如果程序二必須要使用程序一的結果,那麼程序一之後設定p,在程序二之前設定v。
程序一:
s 1**;
p;程序二:
v;s 2**;
訊號量的使用可以方便程序的流暢進行,排除忙等待,訊號不會丟失 ; 但是使用過多的pv操作會大大增加程式的複雜性,難以維護而且容易出現死鎖。
訊號量使用特點總結:互斥訊號量使用在同乙個程序,同步訊號量使用在不同程序,多個p操作在一起時順序無所謂,多個v操作在一起時往往同步的v在前。
七、死鎖(一般導致死鎖的資源是不可搶占資源)。
我們討論死鎖問題的三個必要設定:
(1)若只考慮單個程式執行,系統可以滿足任何乙個程序要求的最大資源。
(2)乙個程序在執行時申請的資源全部滿足,則它可以在有限的時間內執行完成,並且釋放所有占用的資源。
(3)乙個程序只有在它申請的資源不能滿足時,才會被掛起。
死鎖:死鎖是兩個或多個程序中的沒乙個程序都在等待別的程序釋放資源,而無法繼續執行的現象,而且此時系統資源耗盡,也沒有其他的程序釋放資源。
上文提到導致死鎖的資源一般是不可搶占的資源,那麼死鎖的原因是什麼呢?
系統提供的資源有限,不能滿足所有併發的程序的需求;多道程式執行時會有資源釋放、占用順序的不合理;同步通訊的資訊處理不當。
因為我們無法解決導致死鎖的兩個根本原因,所以我們要通過破壞死鎖的必要條件來解決死鎖問題。
死鎖的必要條件:
(1)互斥:存在臨界資源,乙個程序在資源沒釋放之前必要等待。
(2)保持與等待:乙個程序已經分配了一些資源,但是不足以讓自己完成執行,它等待別的程序釋放資源,然而不釋放自己的資源。
(3)不可搶占:乙個程序占用了不可搶占的資源,別的程序或者系統無法強行搶回。
(4)迴圈等待:多個程序的情況一樣,都在等待別的程序釋放資源。
死鎖的避免:只是在程序申請資源以後開始動態檢查,檢測資源分配之後系統是否出於安全狀態,若安全則真正分配資源再使用,若不安全就不分配,申請者等待。
安全狀態:所有的程序都可以在有限時間內得到申請的資源。
不安全狀態:反之。
八、經典同步與互斥問題。
1、哲學家進餐問題。
問題描述:有五個哲學家被五根筷子分開,每個哲學家只能思考或者吃飯,只有拿到左右的筷子才可以吃飯,怎麼樣才能讓他們順利吃飯思考?
解決辦法:經分析只有五個人同時拿起筷子時才會導致死鎖,所以我們用乙個訊號量number來規定只能由四個人同時拿起筷子,剩下的只要將每根筷子設定乙個訊號量就好。
偽**:
int number=4;
int chopsticks[5]=;
solve(int i) //i表示哪乙個哲學家
while(true)
thinking();//思考
down(number);
down(i);
down((i+1)%5);
eating();//吃飯
up(i);
up((i+1)%5);
up(number);
2、讀者-寫者問題。
問題描述:讀者寫者共用乙個資料庫,可以多個人一起讀,但是乙個人寫則其他人不能寫或讀,如何讓讀者寫者協調呢?
解決辦法:共用乙個資料庫自然是設定乙個訊號量db保護資料庫,有乙個人讀就不能有人寫,所以只設定第乙個讀者改變db的值,而必要的是記錄讀者人數reader,然而多個讀者不能同時改變reader值,所以設定乙個訊號量readercontrol保護reader。
int reader=0;
int readercontrol=1;
int db = 1;
void reader()
while(true)
down(readercontrol);
reader++;
if(reader==1)
down(db);
up(readercontrol);
reading();//讀
down(readercontrol);
reader--;
if(reader==0)
up(db);
up(readercontrol);
void writer()
while(true)
down(db);
writing();//寫
up(db);
存在乙個問題:寫者可能會等待很久,所以此方法也稱讀者優先。
作業系統 第二章 作業系統基礎操作
計算機體系結構概述 計算機記憶體和硬碟布局 開機順序 背景中斷 異常和系統呼叫相比較 中斷和異常處理機制 系統呼叫概念 系統呼叫的實現 程式呼叫與系統呼叫的不同之處開銷 2 disk 存放os 3 bios 存放i o處理系統 4 bios 載入os到記憶體中。5 post 加電自檢 尋找顯示卡和執...
作業系統 二 作業系統結構
好好學習,天天向上本文已收錄至我的github倉庫daydayup 使用者介面 程式執行 i o 操作 檔案系統操作 通訊 錯誤檢測 增值服務 資源分配 統計 保護和安全 作業系統服務 作業系統程式介面 系統呼叫 作業系統使用者介面 系統程式 既然作業系統有這麼多的服務,那麼我們平時是怎麼去使用作業...
作業系統基礎
乙個計算機系統主要包括處理器 記憶體 硬碟 鍵盤 滑鼠等輸入輸出裝置。但是硬體的操作十分複雜繁瑣,程式設計師無法全部掌握,因此需要使用作業系統處理這些硬體。作業系統位於計算機硬體和應用軟體之間,本質是乙個軟體。它有作業系統的核心以及系統呼叫兩部分構成。核心 執行於核心態,管理硬體資源 系統呼叫 執行...