バンカーズアルゴリズム [学習アルゴリズム]
序文
2023-8-14 18:18:01
以下のコンテンツは「[学習アルゴリズム]」からのものであり
、学習とコミュニケーションのみを目的としています。
著作権
他のプラットフォームで公開する場合は、次の単語を削除してください。この
記事は最初に CSDN プラットフォームで公開されました。
著者は CSDN@日星月云です。
ブログのホームページは https://blog.csdn.net/qq_51625007 です。
他のプラットフォームで公開する場合は上記の文言を使用してください。
推薦する
第 3 章 プロセッサのスケジューリングとデッドロック [オペレーティング システム]: 7. デッドロックの回避
銀行家のアルゴリズム
7. デッドロックを回避する
7.1 システムのセキュリティステータス
デッドロック回避手法では、システムの状態を安全な状態と危険な状態に分類する。システムが安全な状態であれば、デッドロックを回避できます。逆に、システムが危険な状態にある場合、デッドロック状態に陥る可能性があります。
1 安全な状態
この方法では、プロセスはリソースを動的に申請できますが、システムはリソースを割り当てる前に、まずこのリソース割り当てのセキュリティを計算する必要があります。この割り当てによってシステムが安全でない状態にならない場合は、リソースをプロセスに割り当てることができますが、割り当てられない場合はプロセスが待たされることになります。
2 安全な状態から危険な状態への遷移
リソースが安全な順序で割り当てられない場合、システムは安全な状態から安全でない状態に移行する可能性があります。
システムの安全状態の概念を確立すると、デッドロックを回避する基本的な考え方は、システムが常に安全な状態にあることを保証することであることがわかります。システムは最初は安全な状態にあります。プロセスが使用可能なリソースを要求すると、システムはプロセスの要求を計算する必要があります。プロセスにリソースを割り当てた後もシステムがまだ安全な状態にある場合は、リソースが割り当てられます。プロセスへ。
7.2 バンカーのアルゴリズムを使用してデッドロックを回避する
1 バンカーアルゴリズムのデータ構造
バンカー アルゴリズムを実装するには、システム内で利用可能なリソース、すべてのプロセスによるリソースの最大需要、システム内のリソース割り当て、およびその数を記述するために使用される 4 つのデータ構造をシステム内に設定する必要があります。リソースはすべてのプロセスに必要です。
(1) 利用可能なリソース ベクトル 利用可能。これは、m 個の要素を含む配列です。各要素は、あるタイプの使用可能なリソースの数を表します。その初期値は、システム内で構成されているこのタイプのすべての使用可能なリソースの数です。その値は、このタイプの割り当ておよび割り当てによって変化します。リソースをリサイクルし、動的に変更します。Available[j]=K の場合、システム内に K 個の既存の Rj リソースがあることを意味します。
(2) 最大需要マトリックス これは、システム内の n 個のプロセスのそれぞれに対する m 種類のリソースの最大需要を定義する n×m 行列です。Max[i,j]=K の場合、プロセス i が必要とする Rj タイプのリソースの最大数が K であることを意味します。
(3) 割り当て行列 割り当て。これは n × m 行列でもあり、システム内のリソースの種類ごとに、各プロセスに現在割り当てられているリソースの数を定義します。Allocation[i,j]=K の場合、プロセス i に現在割り当てられている Rj タイプのリソースの数が K であることを意味します。
(4) 需要マトリックス 必要性。これは、各プロセスが依然として必要とするさまざまなリソースの数を表すために使用される n × m 行列でもあります。Need[i,j]=K の場合、プロセス i がタスクを完了するためにタイプ Rj の K 個のリソースがまだ必要であることを意味します。
上記の 3 つの行列の間には次の関係があります。
必要[i,j]=最大[i,j]-割り当て[i,j]
2 バンカーのアルゴリズム
Requesti をプロセス Pi のリクエスト ベクトルとします。Requesti[j]=K の場合、プロセス Pi にはタイプ Rj の K 個のリソースが必要であることを意味します。Pi がリソース要求を送信すると、システムは次の手順に従ってチェックします。
(1) Requesti[j]≦Need[i,j]の場合は(2)へ進み、それ以外の場合は必要なリソース数が公表した最大値を超えているためエラーとみなします。
(2) Requesti[j]≤Available[j]の場合はステップ(3)に進み、そうでない場合は十分なリソースがないことを意味し、Pi は待機する必要があります。
(3) システムは、Pi を処理するためにリソースを暫定的に割り当て、データ構造内の値を変更します。
(4) システムは、このリソース割り当て後にセキュリティ アルゴリズムを実行して、システムが安全な状態にあるかどうかを確認します。安全な場合、リソースはプロセス Pi に正式に割り当てられ、この割り当てが完了します。そうでない場合、この試行割り当ては無効になり、元のリソース割り当てステータスが復元され、プロセス Pi は待機します。
3 セキュリティアルゴリズム
システムによって実行されるセキュリティ アルゴリズムは次のように説明できます。
(1) 2 つのベクトルを設定します: ① 作業ベクトル Work, システムがプロセスの実行を継続するために提供できるさまざまなリソースの数を表します. これには m 個の要素が含まれます. セキュリティ アルゴリズムの実行開始時, Work=Available; ②終了: プロセスに操作を完了するのに十分なリソースがシステムに割り当てられているかどうかを示します。最初は、Finish[i]=false に設定し、プロセスに十分なリソースが割り当てられたら、Finish[i]=true に設定します。
(2) 以下の条件を満たすプロセスをプロセス集合から検索します。
①終了[i]=false;
②必要[i,j]≤仕事[j];
見つかった場合は手順 (3) を実行し、見つからなかった場合は手順 (4) を実行します。
(3) プロセス Pi がリソースを取得した後、完了して割り当てられたリソースが解放されるまでスムーズに実行できるため、次のように実行する必要があります。
作業[j] = 作業[j] + 割り当て[i,j];
終了[i] = true;
ステップ 2 に進みます。
(4) すべてのプロセスの Finish[i]=true が満たされる場合、システムは安全な状態にあることを意味し、そうでない場合、システムは非安全な状態にあることを意味します。
Javaアルゴリズムの実装
コード
package os.chapter3._3_6_1;
import java.util.Arrays;
public class BankerAlgorithm {
private final int[][] max; // 最大需求矩阵
private final int[][] allocation; // 已分配矩阵
private final int[][] need; // 剩余需求矩阵
private final int[] available; // 可用资源向量
private final int processNum; // 进程数量
private final int resourceNum; // 资源数量
public BankerAlgorithm(int[][] max, int[][] allocation, int[] available) {
this.max = max;
this.allocation = allocation;
this.need = new int[max.length][max[0].length];
this.available = available;
this.processNum = max.length;
this.resourceNum = max[0].length;
initNeed();
}
public void initNeed(){
for (int i = 0; i < processNum; i++) {
for (int j = 0; j < resourceNum; j++) {
this.need[i][j] = max[i][j] - allocation[i][j];
}
}
}
// 银行家算法
public void bankerAlgorithm(int[] request,int p) {
System.out.println("==========================================");
System.out.println("检查初始时的安全性");
//初始时刻的安全性
int[] safeSequence = safetyCheck();
if (safeSequence==null){
System.out.println("初始时系统不安全");
}else{
// 输出安全序列
System.out.println("Safe Sequence:");
for (int i : safeSequence) {
System.out.print("P" + i + " ");
}
System.out.println();
}
System.out.println("==========================================");
System.out.println("检查是否满足条件1");
for(int j=0;j<resourceNum;j++){
if(request[j]>need[p][j]){
System.out.println("P"+p+"所需要的资源已超过它所宣布的最大值");
return;
}
}
System.out.println("检查是否满足条件2");
for(int j=0;j<resourceNum;j++){
if(request[j]>available[j]){
System.out.println("尚无足够资源,P"+p+"必须等待");
return;
}
}
System.out.println("==========================================");
//试探分配
System.out.println("开始试探分配");
System.out.println("P"+p+":"+Arrays.toString(request));
for(int j=0;j<resourceNum;j++){
available[j]=available[j]-request[j];
allocation[p][j]=allocation[p][j]+request[j];
need[p][j]=need[p][j]-request[j];
}
System.out.println("开始安全检查");
int[] s = safetyCheck();
if (s!=null) {
System.out.println("可以分配"+"P"+p+":"+Arrays.toString(request));
} else {
System.out.println("不能分配"+"P"+p+":"+Arrays.toString(request));
}
System.out.println("==========================================");
}
// 安全性检查算法
public int[] safetyCheck() {
int[] work; // 工作向量
work = Arrays.copyOf(available, available.length);
boolean[] finish = new boolean[processNum]; // 进程是否完成执行的标志
int[] safeSequence = new int[processNum]; // 安全序列
int count = 0; // 记录已完成的进程数量
// 初始化完成标志数组
for (int i = 0; i < processNum; i++) {
finish[i] = false;
}
// 寻找可执行的进程直到全部进程执行完毕或者找不到可执行的进程
while (count < processNum) {
boolean found = false;
// 遍历所有进程,查找满足资源需求的进程
for (int i = 0; i < processNum; i++) {
if (!finish[i] && checkResources(i,work)) {
for (int j = 0; j < resourceNum; j++) {
work[j] += allocation[i][j];
}
finish[i] = true;
safeSequence[count] = i;
count++;
found = true;
}
}
// 如果没有找到满足资源需求的进程,则认为系统不安全
if (!found) {
return null;
}
}
return safeSequence;
}
// 检查进程的资源需求是否小于等于可用资源
private boolean checkResources(int process,int[] work) {
for (int i = 0; i < resourceNum; i++) {
if (need[process][i] > work[i]) {
return false;
}
}
return true;
}
public static void main(String[] args) {
int[][] max = {
{
7, 5, 3}, {
3, 2, 2}, {
9, 0, 2}, {
2, 2, 2}, {
4, 3, 3}};
int[][] allocation = {
{
0, 1, 0}, {
2, 0, 0}, {
3, 0, 2}, {
2, 1, 1}, {
0, 0, 2}};
int[] available = {
3, 3, 2};
BankerAlgorithm banker = new BankerAlgorithm(max, allocation, available);
int[] request1={
1,0,2};
banker.bankerAlgorithm(request1,1);
int[] request4={
3,3,0};
banker.bankerAlgorithm(request4,4);
int[] request0={
0,2,0};
banker.bankerAlgorithm(request0,0);
}
}
結果
==========================================
检查初始时的安全性
Safe Sequence:
P1 P3 P4 P0 P2
==========================================
检查是否满足条件1
检查是否满足条件2
==========================================
开始试探分配
P1:[1, 0, 2]
开始安全检查
可以分配P1:[1, 0, 2]
==========================================
==========================================
检查初始时的安全性
Safe Sequence:
P1 P3 P4 P0 P2
==========================================
检查是否满足条件1
检查是否满足条件2
尚无足够资源,P4必须等待
==========================================
检查初始时的安全性
Safe Sequence:
P1 P3 P4 P0 P2
==========================================
检查是否满足条件1
检查是否满足条件2
==========================================
开始试探分配
P0:[0, 2, 0]
开始安全检查
不能分配P0:[0, 2, 0]
==========================================
Process finished with exit code 0
やっと
2023-8-14 18:20:16
私たち全員に明るい未来があります
大学院受験の成功を祈り、
仕事での
成功を祈り、欲しいものを手に入れて
ください、いいね、集めて、フォローしてください。