2.19.2デッドロックの条件
- 必要条件
- 相互に排他的:一度に1つのリソースを使用できるのは1つのプロセスのみです
- 占有して待機:プロセスが他のリソースを待機している間、既存のリソースを占有し続けます
- 非プリエンプション:プロセスは、別のプロセスによって占有されているプロセスを強制することはできません
- 充分条件
- 循環待機:閉じたプロセスチェーンがあり、各プロセスはチェーン内の次のプロセスに必要な少なくとも1つのリソースを占有します
2.19.3デッドロックの解決
- デッドロック防止:デッドロックを防止するための4つの条件の1つ
- デッドロックの回避:ループ待機の発生を防止します
- デッドロックの検出と削除
2.20デッドロックの防止
- 間接的な方法:デッドロックを防ぐために必要な3つの条件の1つ
- 相互排除を防ぐ:防ぐことはできません
- 所有と待機の防止:必要なすべてのリソースを一度に要求するプロセスを要求します(効率が低く、必要なリソースを見積もる必要があります)
- 非プリエンプションの防止:リソースを占有するプロセスがリソースを要求した後、占有されたリソースを解放するか、オペレーティングシステムがリソースを解放するために別のプロセスを必要とします(リソースの状態を簡単に保存できる構造が必要です)
- 直接法:ループ待機の出現を防ぐ
- 周期的な待機の防止:リソースを要求する順序を定義します。リソースのすべての要求は、リソースシーケンス番号が増加する順序で厳密に行う必要があります(非効率的)
2.21デッドロックの回避
- 安全でない状態に入らないようにする
- デッドロック防止との比較:3つの必要条件を許可する
- 動的チェック:リソースを適用するプロセスの結果が実行中のプロセス中に安全かどうかをチェックします。デッドロックが発生する場合はブロックされ、そうでない場合は割り当てられます。
- デッドロックを回避する2つの方法
- リソース割り当ての拒否:プロセスがリソース要求を増やしてデッドロックが発生した場合、要求は拒否されます
- プロセス開始の拒否:プロセス要求によってデッドロックが発生した場合、プロセスの開始を拒否します
2.21.1銀行家のアルゴリズム
これは、1965年にダイクストラによって提案されたリソース割り当て拒否戦略です。
思想
ユーザーがリソースのグループを申請すると、システムは、割り当て後も安全な状態にあるかどうかを判断します。安全な状態の場合、割り当ては許可されます。そうでない場合は、割り当てられず、ユーザープロセスがブロックされます。
安全な状態
リソース割り当てには少なくとも1つのセキュリティシーケンスがあります。このシーケンスに従ってリソースを割り当てると、デッドロックが発生することなく終了できます。したがって、セキュリティシーケンスがない場合は、安全でない状態を意味します。
安全状態の判断
- クレームマトリックス(以下、Cマトリックスと呼びます):各プロセスがクレームするリソースの数
- 割り当てマトリックス(以下、Aマトリックスと呼びます):各プロセスに割り当てられたリソースの数
- CAマトリックス:リクエストマトリックスとも呼ばれます:各プロセスに必要なリソースの数
- リソースベクトル(以下、Rベクトルと呼びます):さまざまなリソースの初期合計量
- 利用可能なベクトル(以下、Aベクトルと呼びます):さまざまなリソースの残りの利用可能な量
方法:
- 現在のAベクトルがCAの1行を満たすことができるかどうかを確認します
- 満足している場合は、A行列の対応する行をAベクトルに追加し、3を続行します。それ以外の場合は、安全ではありません。
- 1を繰り返す
- セキュリティシーケンスを取得するためのCAは0です
図:
P2、P1、P3、P4としてセキュリティシーケンスを取得します
- セキュリティシーケンスは一意ではありません。AベクトルがCAマルチラインを満たす場合、複数のシーケンスを試すことができます。
- 安全状態は必ずしもデッドロックではありません。安全状態では、割り当てが安全シーケンスに従っていない場合、デッドロックが発生します。
- すべての危険な状態がデッドロック状態であるとは限りません
//全局数据结构
struct state {
int resource [ m ] ;
int available [ m ];
int claim [ n ][m ] ;
int alloc [ n ][m ] ;
}
//资源分配算法主体
if (alloc [ i,* ] + request [*]> claim [ i,* 〕)
<error >; /*total request > claim* /
else if (request [ * ] > available [ * ])
<suspend process >;
else { /*simulate alloc */
<define newstate by :
alloc [ i,* ]= alloc [ i,* ]+request [ * ];
available [*] = available [ * ] - request [* ] >;
}
if (safe ( newstate ) )
< carry out allocation >;
else {
<restore original state >;
<suspend process >;
}
//银行家算法测试安全性
boolean safe (state s) {
int currentavail[m];
process rest [<number of processes>];
currentavail = available;
rest = {
all processes};
possible = true;
while (possible) {
<find a process Pk in rest such that
claim [k,* ] - alloc [k,* ] <= currentavail;>
if (found) {
/*simulate execution of Pk */
currentavail = currentavail + alloc [ k,*];
rest = rest - {
Pk};
}
else possible = false;
}
return ( rest ==null );
}
2.21.2デッドロック回避の評価
- 利点
- デッドロック防止でのプリエンプションとロールバックの必要はありません
- デッドロック防止よりも制限が少ない
- 不利益
- 最初に、各プロセス宣言によって要求されたリソースを取得する必要があります。つまり、クレームマトリックスが必要です。
- プロセスの実行順序は必須ではありません。そうでない場合、安全な順序に従うことができません。
- 割り当てられるリソースの数は固定する必要があります
- リソースを保持しているプロセスは終了できません
2.22デッドロックの検出と解放
2.22.1アルゴリズムの手順
- A行列のすべてのゼロ行をマークします
- Wベクトルの初期化=ベクトル
- CAマトリックスで添え字iのあるプロセス行を見つけます。マークされておらず、この行は<= Wベクトルです。見つからない場合は、アルゴリズムを終了します。
- そのような行を見つけたら、プロセスiをマークし、A行列の対応する行をWベクトルに追加して、3を返します。
- 3が終了した場合にのみ、マークされていないプロセスが存在し、デッドロックが発生します。マークされていないプロセスはデッドロックされます。
2.22.1リソース割り当てマップの検出方法
リソース割り当て図の簡略化
- すべての要求を満たすノードPiを見つけ、そのすべての要求と分散エッジを削除して、分離ノードにします
- 単純化できなくなるまで1を繰り返します
例
完全に単純化できる場合はデッドロック
はありません完全に単純化できない場合はデッドロックが発生します(以下を参照)
2.22.2デッドロックリリース
- デッドロックが存在しなくなるまで、デッドロックプロセスを元に戻します。
- ロールバック、前に定義した特定のチェックポイントにフォールバックし、すべてのプロセスを再起動します
- プリエンプション、デッドロックがなくなるまで継続的なプリエンプション
では、どのプロセスが撤回されますか?どのプロセスリソースを差し押さえる必要がありますか?
選択原理:これまでのところ、出力が少なく、残り時間が長く、優先度が低く、CPU時間の消費が少ない