1: 実験テーマ
バンカーアルゴリズムのシミュレーションと実現
2: 実験の目的
(1) プロセスの同時実行について詳しく学びます。
(2) プロセスのデッドロックについての理解を強化し、安全な状態と危険な状態の概念を理解します。
(3) デッドロックの問題を回避するためにバンカーのアルゴリズムの使用をマスターします。
3. 全体的な設計 (背景知識、基本原理とアルゴリズム、またはモジュールの導入、設計手順などを含む)
背景知識と理論的根拠:
1. プロセスの同時実行: 複数のプロセスが同時に実行され、システム リソースを共有するため、リソースの競合やデッドロックの問題が発生する可能性があります。
2. デッドロック: リソースの競合によりプロセスが無限待機状態に陥り、実行を続行できなくなります。
3. 安全な状態と安全でない状態: 安全な状態とは、システムがすべてのプロセスをスムーズに完了できるようにリソースの割り当て順序を見つけることができることを意味し、安全な状態とは、そのような割り当て順序が見つからないことを意味します。
バンカーのアルゴリズム原理:
バンカーのアルゴリズムは、プロセスのデッドロックを回避するために使用されるリソース割り当て戦略です。リソースの最大需要と割り当てられたリソースの量に基づいてシステムが安全な状態であるかどうかを判断し、安全な状態にある場合はリソースを割り当て、そうでない場合は待機します。
設計手順:
1. プロセスとリソースのデータ構造を定義する: プロセスの識別、最大需要、割り当て量、需要量、リソースの総量と利用可能量などの情報を表現する必要があります。
2. バンカーアルゴリズムの安全状態チェックを実現します。すべてのプロセスを横断し、リソース割り当てプロセスをシミュレートし、システムが安全な状態にあるかどうかを判断します。
3. リソース割り当て戦略を実現します。プロセスの最大需要と割り当て量に従ってリソースを割り当て、システム リソースのステータスを更新します。
四。詳細設計(主要データ構造、プログラムフローチャート、キーコード等を含む)
主なデータ構造:
プロセス構造: プロセス識別、最大需要、割り当て量、需要量などの情報が含まれます。
リソース構造: リソースの合計量と利用可能な量が含まれます。
*ループに入り、ユーザーが入力したリソース要求を受け取ります。
※リクエストが合法かどうかを判断し、合法であればリソースの割り当てを試みます。
※システムがセキュリティ状態にあるかどうかを判断するバンカーのアルゴリズムに従ってセキュリティ状態を確認します。
* システムが安全な状態にある場合は、リソースを割り当て、システム状態を更新します。
*割り当て結果とシステムステータスを出力します。
データ構造
プロセス数 n
リソースクラスの数 m
利用可能なリソース ベクトル
m 個の要素を含む配列。各要素はクラスで利用可能なリソースの数を表します。Available[j]=K の場合、システム内にタイプ Rj のリソースが K 個あることを意味します。
最大需要マトリックス Max
n×m 行列。m 種類のリソースに対するシステム内の n プロセスのそれぞれの最大需要を定義します。Max[i,j]=K の場合、プロセス i が必要とする Rj タイプのリソースの最大数が K であることを意味します。
割り当てマトリックスの割り当て
n×m 行列。システム内のリソースの種類ごとに、各プロセスに現在割り当てられているリソースの数を定義します。Allocation[i,j]=K の場合、プロセス i に割り当てられた Rj タイプのリソースの数が K であることを意味します。
需要マトリックス ニーズ
n×m マトリックスは、各プロセスで依然として必要とされるさまざまなリソースの数を表すために使用されます。Need[i,j]=K の場合、プロセス i がタスクを完了するためにタイプ Rj の K 個のリソースがまだ必要であることを意味します。
必要[i,j]=最大[i,j]-割り当て[i,j]
セキュリティチェックアルゴリズム
2 つの作業ベクトルを設定する
Work はシステムで現在利用可能なリソースの量を記録します。初期値は「Available」です。
finish はすべての処理が実行されたかどうかを記録します。初期値は長さ n のベクトルで、すべての値は False です。
プロセスセットの中から以下の条件を満たすプロセスを検索します。
終了 == False;
必要 <= 仕事;
見つかった場合は 3 に進み、見つからない場合は 4 に進みます。
プロセスがリソースを取得すると、完了してリソースが解放されるまでスムーズに実行できます。
仕事 + = 割り当て;
終了=真;
実行2
すべてのプロセスがfinish=Trueの場合は安全であることを意味しますが、それ以外の場合はシステムは安全ではありません。
*ユーザーはリソースのリクエストを続けるか、プログラムを終了するかを選択できます。
キーコード:
void 初期()
{
int i;
int j;
printf("プロセス番号を入力してください:\n");
scanf("%d",&n);
printf("リソース クラス番号を入力してください:\n");
scanf("%d",&m);
printf("利用可能なリソース ベクトルを入力してください:\n");
利用可能 = (int*)malloc(sizeof(int)*m);
for(i=0; i<m; i++)
scanf("%d",&Available[i]);
printf("最大需要行列を入力してください:\n");
Max = (int**)malloc(sizeof(int*)*n);
for(i=0; i<n; i++)
{
Max[i] = (int*)malloc(sizeof(int)*m);
for(j=0; j<m; j++)
scanf("%d",&Max[i][j]);
}
printf("割り当てマトリックスを入力してください:\n");
割り当て = (int**)malloc(sizeof(int*)*n);
for(i=0; i<n; i++)
{
割り当て[i] = (int*)malloc(sizeof(int)*m);
for(j=0; j<m; j++)
scanf("%d",&Allocation[i][j]);
}
必要 = (int**)malloc(sizeof(int*)*n);
for(i=0;i<n;i++)
{
Need[i] = (int *)malloc(sizeof(int)*m);
for(j=0;j<m;j++)
必要[i][j] = 最大[i][j] - 割り当て[i][j];
}
}
無効なリクエスト()
{
int i,id;
new_request = (リクエスト*)malloc(sizeof(リクエスト));
new_request->req_src = (int*)malloc(sizeof(int)*m);
printf("プロセスの ID を入力してください\n");
scanf("%d",&id);
new_request->id = id - 1;
printf("プロセス アプリケーション リソース ベクトルを入力してください\n");
for(i=0; i<m; i++)
scanf("%d",&new_request->req_src[i]);
}
ボイドプロセス()
{
int i = new_request->id;
if(vector_compare(Need[i],new_request->req_src,m))
{
if(vector_compare(利用可能,new_request->req_src,m))
{
Vector_sub(利用可能,new_request->req_src,m);
Vector_add(Allocation[i],new_request->req_src,m);
Vector_sub(Need[i],new_request->req_src,m);
安全な検出();
}
それ以外
{
printf("プログラムによって要求されたリソースはシステムの現在の残りリソースより大きいため、実行は延期されます!\n");
戻る;
}
}
それ以外
{
printf("プログラムが要求したリソースがプログラムが要求したリソースを超えているため、実行できません!\n");
戻る;
}
もし(安全)
{
printf("システム セキュリティ、プロセスは実行できます!\n");
戻る;
}
それ以外
{
printf("システムが安全ではないため、プロセスを実行できません!\n");
Vector_add(利用可能,new_request->req_src,m);
Vector_sub(Allocation[i],new_request->req_src,m);
Vector_add(Need[i],new_request->req_src,m);
戻る;
}
}
bool セーフ_検出()
{
int *work = 利用可能;
bool *finish = (bool*)malloc(sizeof(bool)*n);
int i;
//初期化終了
for(i=0; i<n; i++)
終了[i] = False;
for(i=0; i<n; i++)
{
if(finish[i]==False&&vector_compare(work,Need[i],m))
{
printf("プロセス %d を実行してみます\n", i+1);
Vector_add(work,Allocation[i],m); //プロセスを実行してリソースを解放してみる
終了[i] = True;
i = -1; //割り当ててみた後、i++を考慮して最初から実行可能なプロセスが残っているかどうかを確認するため、ここでは-1
}
}
for(i=0; i<n; i++)
if(フィニッシュ[i]==False)
壊す;
if(i==n)
安全 = True;
それ以外
安全 = False;
}
5: 実験結果と分析
このコードは、バンカーのアルゴリズムの安全性チェック部分を実装します。バンカー アルゴリズムは、システムがデッドロック状態に陥るのを防ぐために使用されるリソース割り当ておよびスケジューリング アルゴリズムです。プロセスの最大リソース要件と現在利用可能なリソースを事前に計算し、すべてのプロセスが実行を完了できるように、安全なシーケンスがあるかどうかを判断します。
以下は、コードのセキュリティ チェック部分の分析です。
1.safe_detect() 関数はセキュリティチェックに使用されます。現在のシステムで利用可能なリソース ベクトル、Available、プロセスの最大需要行列 Max、および割り当て行列 Allocation を入力として受け入れます。
2. 補助配列 work とブール配列finish が関数内に作成され、作業ベクトルとプロセスの完了ステータスを記録します。
3. 終了配列を初期化し、すべてのプロセスの完了ステータスを False に初期化します。
4. セキュリティ チェックの主なロジックはループ トラバーサルです。各プロセス i について、その完了ステータスが False であり、現在利用可能なリソース作業量がプロセス i の需要ベクトル Need[i] 以上であると判断します。条件が満たされた場合、プロセス i を実行できることを意味します。つまり、プロセスを実行して対応するリソースを解放しようとします。
5. プロセス i の実行を試行した後、プロセス i の完了ステータスを True に設定し、プロセス i に割り当てられたリソースの量だけ利用可能なリソース ベクトルの作業を増加します。
6. 最初にループバックし、条件を満たすプロセスが見つからなくなるか、すべてのプロセスが完了としてマークされるまで、条件を満たす次のプロセスの検索を続けます。
最後に、すべてのプロセスが完了としてマークされていることを確認します。そうである場合、システムは安全であるとみなされ、変数safeがTrueに設定され、そうでない場合、safeはFalseに設定されます。
実験では、さまざまなプロセスやリソースの状況をシミュレートしてテストできます。入力されたプロセスリソース要求に従って、システムはバンカーのアルゴリズムに従ってリソースを割り当て、割り当て結果とシステムステータスを出力します。システムが安全な状態にあるかどうか、およびリソースの割り当てを観察できます。
6. まとめと経験
この実験を通じて、プロセスの同時実行とデッドロックの問題をさらに理解し、バンカーのアルゴリズムの原理と実装を学びました。実際のコーディングを通じてバンカーのアルゴリズムを実現することで、アルゴリズムの理解が深まり、プログラミング能力が向上します。同時に、実験のプロセスを通じて、リソースの競争とセキュリティステータスの概念をより深く理解し、デッドロックの問題を回避する方法について明確なアイデアを持ちました。実験結果を分析することで、システムのセキュリティとリソース割り当て戦略の有効性をより適切に評価でき、実際のシステム設計と開発に役立つ経験が得られます。