Operating Systems. Exercise 08

I. プロセス間でのメモリ共有2 (準備課題, 配点無し)
共有メモリは別々のプロセスで読み書きするため, 値が書き換わるような共有メモリ上の変数にアクセスする場合
読み書きのタイミングを計る必要があります。

この場合意図したように動かすためには, 県と市の書き換えという一連の書き込み処理中に
他プロセスからの資源へのアクセスを制限する必要があり, それを排他制御と呼びます。

共有メモリを使った場合の排他制御の仕組みを考えてみます。
例えば以下のように共有メモリ上に確保した変数flagを作って上手くいくでしょうか?

プロセス1

   //プロセス2が資源を使用中である間待つ
1: while (flag == 1) {}
2:
   //プロセス1が資源を使用中であることを明示
3: flag = 0;
4
   //クリティカルな処理
5: ...
6: ...
7: ...
	    
プロセス2

   //プロセス1が資源を使用中である間待つ
1: while (flag == 0) {}
2:
   //プロセス2が資源を使用中であることを明示
3: flag = 1;
4
   //クリティカルな処理
5: ...
6: ...
7: ...
	    

この場合初期状態でflag=0だとすると, プロセス1が実行された後, プロセス2は永遠に実行されません。


以下ならどうでしょうか?
プロセス1

   //プロセス2が資源を使用中である間待つ
1: while (flag == 1) {}
2:
   //クリティカルな処理
3: ...
4: ...
5: ...
   //プロセス2へ処理を譲る
6: flag = 1;
	    
プロセス2

   //プロセス1が資源を使用中である間待つ
1: while (flag == 0) {}
2:
   //クリティカルな処理
3: ...
4: ...
5: ...
   //プロセス1へ処理を譲る
6: flag = 0;
	    

この場合初期状態でflag=0だとすると, プロセス1, プロセス2, プロセス1, プロセス2の順番で交互に実行されますが
プロセス1とプロセス2が資源を欲するタイミングが交互であるとは限らないので, かなり効率が悪くなる可能性が高いです


Peterson(ピーターソン)のアルゴリズムによる排他制御

排他制御を実現する方法にピーターソンのアルゴリズムがあります。
まず共有メモリ領域に, 排他制御のための変数をいくつか確保します


//1. 共有メモリ使用意志表示 (共有するプロセス数要素の配列になる)
int *naWantPossess;

//2. 優先権
int *nPriority;
      

"1. 共有メモリ使用意志表示"は, プロセス1または2が資源を使用したいかを意思表示する変数で, 共有するプロセス数要素の配列になります。
"2. 優先権"は, どのプロセスがアクセス優先権を持つのか示す変数です。
これらは 共有メモリ領域割当と内容の初期化後, 以下のように使います

プロセス1側

//プロセス1が使用の意志を表示する
naWantPossess[PROCESS1] = TRUE; 

//プロセス2に優先権を与えて処理を促す
*nPriority = PROCESS2;    

//プロセス2に使用意志があり かつ 優先権が有れば whileループで共有メモリへのアクセス保留
while (naWantPossess[PROCESS2] && *nPriority == PROCESS2) { }

/*** 共有メモリ資源へのアクセス ***/
....
....

//プロセス1が使用の意志を撤回する
naWantPossess[PROCESS1] = FALSE; 
      
プロセス2側

//プロセス2が使用の意志を表示する
naWantPossess[PROCESS2] = TRUE; 

//プロセス1に優先権を与えて処理を促す
*nPriority = PROCESS1;    

//プロセス1に使用意志があり かつ 優先権が有れば whileループで共有メモリへのアクセス保留
while (naWantPossess[PROCESS1] && *nPriority == PROCESS1) { }

/*** 共有メモリ資源へのアクセス ***/
....
....

//プロセス2が使用の意志を撤回する
naWantPossess[PROCESS2] = FALSE; 
      
"PROCESS1"と"PROCESS2"は配列インデックスとして使うので, マクロでそれぞれ整数値0と1 にしてあります
TRUEとFALSEも必要に応じて定義します。

II. プロセス間メモリ共有2(配点100%)

課題1

課題: 前回の問題で, 表示がおかしくならないように, ハノイの塔の変数へのアクセスを
ピーターソンのアルゴリズムを使った排他制御によってコントロールして解くように修正してください
共有メモリ領域確保と割当時には、領域のサイズに注意してください (配列は配列要素数分の領域が必要です)

:

ターミナル1 (プロセス1実行)

% ./HanoiExclusiveSolve 30

Share Memory ID = 16089130
(ハノイの塔の円盤移動が行われる)
Number of Moves: 1073741823
Number of Disks: 30
	      
  ターミナル2 (プロセス2実行)

% ./HanoiExclusiveDisplay 16089130

(途中経過が正しく出力される)
Number of Moves: 664670084
Number of Disks: 30
Move: 664670084
.
.
.
| 0|   | 0|   | 0|
| 0|   | 0|   | 0|
| 0|   | 0|   | 0|
| 0|   | 0|   | 0|
| 0|   | 0|   | 0|
| 0|   | 4|   | 0|
| 0|   | 5|   | 0|
| 0|   | 6|   | 1|
| 0|   | 7|   | 2|
| 0|   |18|   |13|
| 0|   |19|   |14|
| 0|   |20|   |15|
| 3|   |21|   |16|
| 8|   |24|   |17|
| 9|   |25|   |22|
|10|   |26|   |23|
|11|   |27|   |28|
|12|   |30|   |29|
----   ----   ----
  A      B      C