ディレクトリ
プロセス間通信
2.3.1レース条件
2.3.2重要な領域
競合状態を回避するための鍵は、読んで、共有リソースへの書き込み、同時に複数のプロセスを防ぐためです。
言い換えれば、我々は、ミューテックスを必要としますmutual exclusion
共有リソースにアクセスするためのプログラムの一部は、重要なゾーンと呼ばれますcritical section
ビジーウェイトと2.3.3排他
割り込みを無効にします
短所:
- ユーザプロセスの近くには、権限は賢明ではありません割り込み。
- システムは、マルチプロセッサ・システムの場合のみの実行に影響を与える割り込みシャットダウンし、その後、
disable
CPUの命令をCPU上で実行されている他のプロセスがまだ共有メモリにアクセスすることができます。
割り込みを無効にすると、多くの場合、オペレーティング・システム自体の内部で有用な技術であるが、ユーザー・プロセスのための一般的な相互排除機構として適切ではありません。
ロック変数
厳格な交替
一部の値が呼び出され表示されるまで、連続変数をテストするビジーウェイト。ビジーウェイトを使用してロックが呼び出されたスピンロック。
短所:
- 連続検出変数廃棄CPU
- それ以外の場合は非効率的な、厳しいと秩序
ピーターソンのソリューション
#define FALSE 0
#define TRUE 1
#define N 2 /* number of processes */
int turn; /* whose turn is it? */
int interested[N]; /* all values initially 0 (FALSE) */
void enter region(int process) /* process is 0 or 1 */
{
int other; /* number of the other process */
other = 1 −process; /* the opposite of process */
interested[process] = TRUE; /* show that you are interested */
turn =process; /* set flag */
while (turn == process && interested[other] == TRUE) /* null statement */ ;
}
void leave region(int process) /* process: who is leaving */
{
interested[process] = FALSE; /* indicate departure from critical region */
}
最初のプロセスなしでクリティカルセクションを入力します。
0のコールを処理しますenter_region
。でそれはinterested
、アレイ内の対応する要素は、その後、1に設定されているture
0。1によるプロセスが呼び出されていないenter_region
、それはenter_region
プロセスが0クリティカル領域を入力し、すぐに戻ります。この時点でプロセス呼び出した場合はenter_region
、その後、interested[0]
行くFALSE
前に、それが待機します。
2つのプロセスがほぼ同時に呼び出された場合enter_region
。これは、turn
番号割当処理が完了した後になります。仮定すると、turn
1。同時に2つのプロセス到達するためのwhile
ステートメントを、プロセス0が終了し、クリティカル領域に入ります。1プロセスがクリティカル領域からプロセス0が終了するまで待機します。
基本的にビジーウェイトであります
TSL命令
TSL Test and Set Lock
2.3.4スリープとウェイクアップ
上記の方法はビジーウェイトが必要です。実際には、本質は次のとおりです。プロセスは、クリティカル領域を入力する必要がある場合、入るかどうかをまずチェックは、あなたが入力できない場合は、それがループを実行します、それは重要な領域に入ることができるまで検出し続けます。
いくつかのバグが存在しますが、CPU時間を消費する待機していないだけで忙しいです。優先順位の逆転が発生した場合、例えば、プロセスは、ロックを解除することができないクリティカルセクションに入っている優先度の高いプロセスをもたらすことは重要な領域に入ることはできません。
生産者 - 消費者問題
また、有限バッファ問題(有界バッファ問題)として知られています。
2つのプロセスは、固定サイズの共通バッファを共有しています。前記プロデューサの、バッファへの情報は、別の消費者は、バッファからメッセージを削除します。
プロデューサーはバッファに新しい項目を入れたいときにトラブルが発生するが、それはすでにいっぱいです。プロデューサーは、消費者が1つ以上の項目を削除したときに起こされるために、スリープ状態にするためのソリューションです。消費者がバッファから項目を削除したいと、バッファが空であることを見ればプロデューサーがバッファに何かを入れて、それを目覚めるまで同様に、それはスリープ状態になります。
バッファ内のオブジェクトの数を追跡するために、我々は変数を必要としますcount
。
#define N 100 /* number of slots in the buffer */
int count = 0; /* number of items in the buffer */
void producer(void)
{
int item;
while (TRUE) { /* repeat forever */
item = produce item( ); /* generate next item */
if (count == N) sleep( ); /* if buffer is full, go to sleep */
inser t item(item); /* put item in buffer */
count = count + 1; /* increment count of items in buffer */
if (count == 1) wakeup(consumer); /* was buffer empty? */
}
}
void consumer(void)
{
int item;
while (TRUE) { /* repeat forever */
if (count == 0) sleep( ); /* if buffer is empty, got to sleep */
item = remove item( ); /* take item out of buffer */
count = count −1; /* decrement count of items in buffer */
if (count == N − 1) wakeup(producer); /* was buffer full? */
consume item(item); /* pr int item */
}
}
しかし、数へのアクセスが間違って行くことができます。カウントはアクセスを制限しない場合は、RECE状態が発生します。バッファが空である、消費者はそれが0であるかどうかをテストするために数えるお読みください。このとき、スケジューラは、消費者が一時停止し、その後、生産を行うことを決定しました。回数を増やし、バッファオブジェクトの数を増やすために生産者は、[OK]をので、今1でなければなりません数えます。この場合には、それは論理的に寝ていないので、メッセージが失われますので、生産者のコードによると、今回の消費者の消費者は、前中断されることに起因する消費者に、しかし実際には、ウェイクアップメッセージを送信します。
消費者が再び実行すると、カウント== 0の前に、それを自分の読書によると、あなたは自分自身をスリープ状態になります。バッファがいっぱいになった直後、プロデューサーは、この時間を睡眠に入った、消費者と生産者の両方が眠ることはありません。
この問題の本質は次のとおりです。ウェイクアップメッセージが本当に眠れないの工程に送られます。
2.3.5セマフォ
1965年には、ダイクストラは、セマフォセマフォの使用を提案しました。セマフォは、それが他の正の整数であるときに、1つまたは複数のウェイクアップが保留された表し、示す任意のウェイクアップ信号を保存しない、それが0である場合、整数変数です。
ダウンとアップダイクストラ2つのセマフォ操作、。セマフォ信号の値をダウンチェック操作量は、それが0でない場合、それは1だけデクリメントされ、0です。それが0であれば、プロセスはスリープしますが、私たちはダウン操作は実行されません。サイズチェック値の大きさの値を変更し、おそらく睡眠に行き、これらの行為は切っても切れない単一原子操作(アトミックアクション)です。セマフォ操作が行われると、操作が完了するか、プロセスがブロックされるまで、他のすべてのプロセスは、セマフォにアクセスすることができます。
セマフォ値の操作まで1ずつインクリメントされます。完了することができ、そのセマフォ上で寝て複数のプロセスがある場合ダウン以前の操作は、 システムがランダムにダウン操作を完了するためのプロセスを選択します。このように、セマフォにアップした後 、その上に寝プロセスと、セマフォはまだ0になりますが、それに寝て1つの少ないのプロセスが存在します。
セマフォを使用した生産者 - 消費者問題の解決
問題(失われたウェイクアップ)ウェイクアップ信号以前に提案された損失を解決するためのセマフォの役割。
#define N 100 /* number of slots in the buffer */
typedef int semaphore; /* semaphores are a special kind of int */
semaphore mutex = 1; /* controls access to critical region */
semaphore empty = N; /* counts empty buffer slots */
semaphore full = 0; /* counts full buffer slots */
void producer(void)
{
int item;
while (TRUE) { /* TRUE is the constant 1 */
item = produce item( ); /* generate something to put in buffer */
down(&empty); /* decrement empty count */
down(&mutex); /* enter critical region */
inser t item(item); /* put new item in buffer */
up(&mutex); /* leave critical region */
up(&full); /* increment count of full slots */
}
}
void consumer(void)
{
int item;
while (TRUE) { /* infinite loop */
down(&full); /* decrement full count */
down(&mutex); /* enter critical region */
item = remove item( ); /* take item from buffer */
up(&mutex); /* leave critical region */
up(&empty); /* increment count of empty slots */
consume item(item); /* do something with the item */
}
}
生産者と消費者がでバッファにアクセスしないことを確認するために、1つが空であるスロットの数をカウントするため、空と呼ばれる、満ちているスロットの数をカウントするためのフルと呼ばれるもの、と呼ばれる1つのmutex:このソリューションは、3つのセマフォを使用しています同時。
1とプロセス信号の複数の量の初期値は、そのような信号の量は、バイナリセマフォ(バイナリセマフォ)と呼ばれる、唯一のプロセスがクリティカルセクションに入ることができることを保証するために使用されます。